Index: include/freeDiameter/libfdproto.h
===================================================================
--- include/freeDiameter/libfdproto.h	(revision 1213)
+++ include/freeDiameter/libfdproto.h	(revision 1230)
@@ -2699,4 +2699,5 @@
 	char *		pei_errcode;	/* name of the error code to use */
 	struct avp *	pei_avp;	/* pointer to invalid (in original message) or missing AVP (to be freed) */
+	int		pei_avp_free;	/* Set to 1 if the pei_avp must be freed */
 	char *		pei_message;	/* Overwrite default message if needed */
 	int		pei_protoerr; 	/* do we set the 'E' bit in the error message ? */
Index: libfdcore/messages.c
===================================================================
--- libfdcore/messages.c	(revision 1228)
+++ libfdcore/messages.c	(revision 1230)
@@ -388,4 +388,9 @@
 		/* Set the error code */
 		CHECK_FCT( fd_msg_rescode_set(m, pei.pei_errcode, pei.pei_message, pei.pei_avp, 1 ) );
+		
+		/* free the pei AVP to avoid memory leak */
+		if (pei.pei_avp_free) {
+			fd_msg_free(pei.pei_avp);
+		}
 		
 		*msg = NULL;
Index: libfdcore/p_ce.c
===================================================================
--- libfdcore/p_ce.c	(revision 1191)
+++ libfdcore/p_ce.c	(revision 1230)
@@ -637,4 +637,8 @@
 	CHECK_FCT_DO( fd_out_send(cer, *recv_cnx, NULL), goto destroy );
 	
+	if (error->pei_avp_free) {
+		fd_msg_free(error->pei_avp);
+	}
+	
 	/* And now destroy this connection */
 destroy:
Index: libfdcore/routing_dispatch.c
===================================================================
--- libfdcore/routing_dispatch.c	(revision 1216)
+++ libfdcore/routing_dispatch.c	(revision 1230)
@@ -610,4 +610,5 @@
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
@@ -632,4 +633,5 @@
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
@@ -656,4 +658,5 @@
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
@@ -674,4 +677,5 @@
 									fd_hook_call(HOOK_MESSAGE_PARSING_ERROR, msgptr, NULL, error_info.pei_message ?: error_info.pei_errcode, fd_msg_pmdl_get(msgptr));
 									CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+									if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 									return 0;
 								} else {
@@ -932,4 +936,5 @@
 						if (error_info.pei_errcode) {
 							CHECK_FCT( return_error( &msgptr, error_info.pei_errcode, error_info.pei_message, error_info.pei_avp) );
+							if (error_info.pei_avp_free) { fd_msg_free(error_info.pei_avp); }
 							return 0;
 						} else {
Index: libfdproto/messages.c
===================================================================
--- libfdproto/messages.c	(revision 1229)
+++ libfdproto/messages.c	(revision 1230)
@@ -2371,4 +2371,7 @@
 	CHECK_FCT_DO( fd_dict_getval(model_avp, &avp_info), return NULL );
 	
+	/* Set an initial size */
+	avp->avp_public.avp_len = GETAVPHDRSZ( avp->avp_public.avp_flags ) + avp_value_sizes[avp_info.avp_basetype];
+	
 	/* Prepare the empty value */
 	memset(&val, 0, sizeof(val));
@@ -2377,4 +2380,5 @@
 			val.os.data = os;
 			val.os.len  = sizeof(os);
+			avp->avp_public.avp_len += val.os.len;
 		case AVP_TYPE_INTEGER32:
 		case AVP_TYPE_INTEGER64:
@@ -2440,4 +2444,5 @@
 			pr_data->pei->pei_errcode = "DIAMETER_MISSING_AVP";
 			pr_data->pei->pei_avp = empty_avp(rule->rule_avp);
+			pr_data->pei->pei_avp_free = 1;
 		}
 		return EBADMSG;
@@ -2453,4 +2458,5 @@
 				pr_data->pei->pei_errcode = "DIAMETER_AVP_OCCURS_TOO_MANY_TIMES";
 			pr_data->pei->pei_avp = empty_avp(rule->rule_avp); /* Well we are supposed to return the (max + 1)th instance of the AVP instead... Pfff... */ TODO("Improve...");
+			pr_data->pei->pei_avp_free = 1;
 		}
 		return EBADMSG;
@@ -2472,4 +2478,5 @@
 					pr_data->pei->pei_message = "AVP was not in its fixed position";
 					pr_data->pei->pei_avp = empty_avp(rule->rule_avp);
+					pr_data->pei->pei_avp_free = 1;
 				}
 				return EBADMSG;
@@ -2485,4 +2492,5 @@
 					pr_data->pei->pei_message = "AVP was not in its fixed position";
 					pr_data->pei->pei_avp = empty_avp(rule->rule_avp);
+					pr_data->pei->pei_avp_free = 1;
 				}
 				return EBADMSG;
