Use the acf/validate_value filter to add custom server-side validation with error messages.
Validate a specific field by name — enforce a minimum word count on a textarea:
<?php
add_filter( 'acf/validate_value/name=description', function ( $valid, $value, $field, $input_name ) {
if ( $valid !== true ) {
return $valid;
}
$word_count = str_word_count( strip_tags( $value ) );
if ( $word_count < 20 ) {
return 'Description must be at least 20 words. Currently: ' . $word_count . '.';
}
return $valid;
}, 10, 4 );
Enforce unique values across posts:
<?php
add_filter( 'acf/validate_value/name=employee_id', function ( $valid, $value, $field, $input_name ) {
if ( $valid !== true || empty( $value ) ) {
return $valid;
}
$existing = get_posts( [
'post_type' => 'staff',
'meta_key' => 'employee_id',
'meta_value' => $value,
'post__not_in' => [ $_POST['post_ID'] ?? 0 ],
'fields' => 'ids',
] );
if ( ! empty( $existing ) ) {
return 'This employee ID is already in use.';
}
return $valid;
}, 10, 4 );
Validate by field type — require all email fields to use a company domain:
<?php
add_filter( 'acf/validate_value/type=email', function ( $valid, $value, $field, $input_name ) {
if ( $valid !== true || empty( $value ) ) {
return $valid;
}
if ( ! str_ends_with( $value, '@example.com' ) ) {
return 'Please use your @example.com email address.';
}
return $valid;
}, 10, 4 );
Return true to pass validation, or a string error message to fail. Always check $valid !== true first to respect earlier validation (e.g. the built-in “required” check).