
Filter Hook since 2.0.0
wp_handle_upload
Filters the result right after a file is moved to the uploads folder
Description
wp_handle_upload fires right after a file physically lands in the uploads directory, before any attachment post exists for it — earlier in the pipeline than add_attachment.
When it runs
Inside wp_handle_upload(), after the file is moved into place but before wp_insert_attachment() creates the corresponding post.
Signature
apply_filters( 'wp_handle_upload', array $upload, string $context );Parameters
uploadarray — Array with 'file' (path), 'url', and 'type' (mime type) keys.contextstring — Either 'upload' (new file) or 'sideload' (imported from elsewhere).
Examples
Basic
add_filter( 'wp_handle_upload', function( $upload ) {
error_log( 'File uploaded to: ' . $upload['file'] );
return $upload;
} );Log the on-disk path of every uploaded file.
Real case
add_filter( 'wp_handle_upload', function( $upload, $context ) {
if ( 'upload' === $context ) {
do_action( 'my_cdn_push', $upload['file'] );
}
return $upload;
}, 10, 2 );Push newly uploaded files straight to a CDN, distinguishing real uploads from sideloads.
Edge case
add_filter( 'wp_handle_upload', function( $upload ) {
// No attachment post exists yet at this point —
// there's no post ID available here, only the file path/URL.
return $upload;
} );This fires before the attachment post is created, so no post ID is available yet.
Common Use Cases
- Push newly uploaded files to a CDN or external storage
- Log or audit raw uploads before a post record exists
- Rewrite the returned file path/URL for a custom storage backend
- Run virus/malware scanning on the raw uploaded file
Common mistakes
- Forgetting to return $upload — an unreturned value breaks the upload response used downstream
- Trying to attach post meta here — no attachment post ID exists yet; use add_attachment or wp_generate_attachment_metadata instead
Related hooks
FAQ
Does an attachment post exist when this filter runs?
No — this fires before wp_insert_attachment() creates the post, so there's no attachment ID available yet.
What’s the difference between ‘upload’ and ‘sideload’ context?
'upload' is a direct user file upload; 'sideload' is a file pulled in programmatically, such as an image imported from a URL.
Source: wp-admin/includes/file.php