diff --git src/wp-admin/includes/ajax-actions.php src/wp-admin/includes/ajax-actions.php
index 5ad5eac8a6..2fc811d3f4 100644
--- src/wp-admin/includes/ajax-actions.php
+++ src/wp-admin/includes/ajax-actions.php
@@ -1497,19 +1497,16 @@ function wp_ajax_add_meta() {
 					);
 					$x->send();
 				}
-
-				$mid = add_meta( $pid );
-				if ( ! $mid ) {
-					wp_die( __( 'Please provide a custom field value.' ) );
-				}
 			} else {
 				wp_die( 0 );
 			}
-		} else {
-			$mid = add_meta( $pid );
-			if ( ! $mid ) {
-				wp_die( __( 'Please provide a custom field value.' ) );
-			}
+		}
+
+		$mid = add_meta( $pid );
+		if ( is_wp_error( $mid ) ) {
+			wp_die( $mid->get_error_message() );
+		} elseif ( ! $mid ) {
+			wp_die( __( 'Please provide a custom field value.' ) );
 		}
 
 		$meta = get_metadata_by_mid( 'post', $mid );
@@ -1538,7 +1535,7 @@ function wp_ajax_add_meta() {
 		if ( is_protected_meta( $meta->meta_key, 'post' ) || is_protected_meta( $key, 'post' ) ||
 			! current_user_can( 'edit_post_meta', $meta->post_id, $meta->meta_key ) ||
 			! current_user_can( 'edit_post_meta', $meta->post_id, $key ) ) {
-			wp_die( -1 );
+			wp_die( __( 'Sorry, you are not allowed to edit this custom field.' ) );
 		}
 		if ( $meta->meta_value != $value || $meta->meta_key != $key ) {
 			$u = update_metadata_by_mid( 'post', $mid, $value, $key );
diff --git src/wp-admin/includes/post.php src/wp-admin/includes/post.php
index ec083c569f..a0198ecb16 100644
--- src/wp-admin/includes/post.php
+++ src/wp-admin/includes/post.php
@@ -889,9 +889,10 @@ function write_post() {
  * Add post meta data defined in $_POST superglobal for post with given ID.
  *
  * @since 1.2.0
+ * @since 5.3.0 Return `WP_Error` if the meta is protected or if the user doesn't have capability.
  *
  * @param int $post_ID
- * @return int|bool
+ * @return int|bool|WP_Error
  */
 function add_meta( $post_ID ) {
 	$post_ID = (int) $post_ID;
@@ -917,7 +918,7 @@ function add_meta( $post_ID ) {
 		}
 
 		if ( is_protected_meta( $metakey, 'post' ) || ! current_user_can( 'add_post_meta', $post_ID, $metakey ) ) {
-			return false;
+			return new WP_Error( 'edit_post_metas', __( 'Sorry, you are not allowed to edit this custom field.' ) );;
 		}
 
 		$metakey = wp_slash( $metakey );
diff --git tests/phpunit/tests/admin/includesPost.php tests/phpunit/tests/admin/includesPost.php
index cad9742f8d..12cce2718a 100644
--- tests/phpunit/tests/admin/includesPost.php
+++ tests/phpunit/tests/admin/includesPost.php
@@ -856,6 +856,22 @@ class Tests_Admin_Includes_Post extends WP_UnitTestCase {
 		$this->assertEquals( '', get_post_meta( $p, 'testkey', true ) );
 	}
 
+	/**
+	 * @ticket 32565
+	 */
+	public function test_post_add_meta_should_return_wp_error_if_protected_meta() {
+		$post_id = self::factory()->post->create();
+
+		$_POST = array(
+			'metakeyinput' => '_testkey',
+			'metavalue'    => 'test_value',
+		);
+
+		wp_set_current_user( self::$admin_id );
+
+		$this->assertWPError( add_meta( $post_id ) );
+	}
+
 	/**
 	 * Test the post type support in post_exists().
 	 *
