diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php
index 6ff2d2d9fd..9fd70f48cb 100644
--- a/src/wp-admin/includes/ajax-actions.php
+++ b/src/wp-admin/includes/ajax-actions.php
@@ -2975,7 +2975,7 @@ function wp_ajax_query_attachments() {
 
 	// Filter query clauses to include filenames.
 	if ( isset( $query['s'] ) ) {
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 	}
 
 	/**
diff --git a/src/wp-admin/includes/post.php b/src/wp-admin/includes/post.php
index 77aadb2135..0be860ea01 100644
--- a/src/wp-admin/includes/post.php
+++ b/src/wp-admin/includes/post.php
@@ -1269,7 +1269,7 @@ function wp_edit_attachments_query_vars( $q = false ) {
 
 	// Filter query clauses to include filenames.
 	if ( isset( $q['s'] ) ) {
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 	}
 
 	return $q;
diff --git a/src/wp-includes/post.php b/src/wp-includes/post.php
index a5bd9678bb..ba80b0111c 100644
--- a/src/wp-includes/post.php
+++ b/src/wp-includes/post.php
@@ -7482,7 +7482,7 @@ function wp_add_trashed_suffix_to_post_name_for_post( $post ) {
 }
 
 /**
- * Filters the SQL clauses of an attachment query to include filenames.
+ * Filters the SQL clauses of an attachment query to include meta (filename/alt).
  *
  * @since 4.7.0
  * @access private
@@ -7493,12 +7493,12 @@ function wp_add_trashed_suffix_to_post_name_for_post( $post ) {
  *                          DISTINCT, fields (SELECT), and LIMITS clauses.
  * @return string[] The modified array of clauses.
  */
-function _filter_query_attachment_filenames( $clauses ) {
+function _filter_query_attachment_meta( $clauses ) {
 	global $wpdb;
 	remove_filter( 'posts_clauses', __FUNCTION__ );
 
 	// Add a LEFT JOIN of the postmeta table so we don't trample existing JOINs.
-	$clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND sq1.meta_key = '_wp_attached_file' )";
+	$clauses['join'] .= " LEFT JOIN {$wpdb->postmeta} AS sq1 ON ( {$wpdb->posts}.ID = sq1.post_id AND ( sq1.meta_key = '_wp_attached_file' OR sq1.meta_key = '_wp_attachment_image_alt'  ) )";
 
 	$clauses['groupby'] = "{$wpdb->posts}.ID";
 
diff --git a/tests/phpunit/tests/query/search.php b/tests/phpunit/tests/query/search.php
index c1c74c8240..38af8fb872 100644
--- a/tests/phpunit/tests/query/search.php
+++ b/tests/phpunit/tests/query/search.php
@@ -455,7 +455,7 @@ class Tests_Query_Search extends WP_UnitTestCase {
 		);
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image1.png', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 
 		// Pass post_type a string value.
 		$q = new WP_Query(
@@ -485,7 +485,7 @@ class Tests_Query_Search extends WP_UnitTestCase {
 		);
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image2.png', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 
 		// Pass post_type an array value.
 		$q = new WP_Query(
@@ -544,7 +544,7 @@ class Tests_Query_Search extends WP_UnitTestCase {
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image4.png', true );
 		add_post_meta( $attachment, '_test_meta_key', 'value', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 
 		// Pass post_type a string value.
 		$q = new WP_Query(
@@ -584,7 +584,7 @@ class Tests_Query_Search extends WP_UnitTestCase {
 		wp_set_post_terms( $attachment, 'test', 'post_tag' );
 
 		add_post_meta( $attachment, '_wp_attached_file', 'some-image5.png', true );
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 
 		// Pass post_type a string value.
 		$q = new WP_Query(
@@ -606,11 +606,45 @@ class Tests_Query_Search extends WP_UnitTestCase {
 		$this->assertSame( array( $attachment ), $q->posts );
 	}
 
+	/**
+	 * @ticket 39004
+	 */
+	public function test_include_file_names_in_attachment_search_with_alt_text() {
+		$attachment = self::factory()->post->create(
+			array(
+				'post_type'    => 'attachment',
+				'post_status'  => 'publish',
+				'post_title'   => 'bar foo',
+				'post_content' => 'foo bar',
+				'post_excerpt' => 'This post has foo',
+			)
+		);
+
+		add_post_meta( $attachment, '_wp_attached_file', 'some-image4.png', true );
+
+		// Add an alt text
+		add_post_meta( $attachment, '_wp_attachment_image_alt', 'Alt text', true );
+
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
+
+		// Pass post_type a string value.
+		$q = new WP_Query(
+			array(
+				's'           => 'Alt text',
+				'fields'      => 'ids',
+				'post_type'   => 'attachment',
+				'post_status' => 'inherit',
+			)
+		);
+
+		$this->assertSame( array( $attachment ), $q->posts );
+	}
+
 	/**
 	 * @ticket 22744
 	 */
-	public function test_filter_query_attachment_filenames_unhooks_itself() {
-		add_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+	public function test_filter_query_attachment_meta_unhooks_itself() {
+		add_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 
 		apply_filters(
 			'posts_clauses',
@@ -625,7 +659,7 @@ class Tests_Query_Search extends WP_UnitTestCase {
 			)
 		);
 
-		$result = has_filter( 'posts_clauses', '_filter_query_attachment_filenames' );
+		$result = has_filter( 'posts_clauses', '_filter_query_attachment_meta' );
 
 		$this->assertFalse( $result );
 	}
