Identify a file rejected by the media route
An integration sends an image to WordPress and receives an error such as rest_upload_no_data or rest_upload_no_content_disposition. You sometimes see a 400 error even though the same file uploads through the media library. This guide addresses the content of a media-creation request: the file bytes and the information telling the server how to read them.
The native media route is /wp/v2/media in the REST API. The public prefix is often /wp-json, but the complete address depends on the installation. A well-formed POST request can create a media-library item and write a file. The proposed tests therefore take place on an authorized private copy, with a small test file and a dedicated account. The commands below assume an installation exposing this native API and allowing the authentication method described. On WordPress.com or another managed platform, first check the URL and access mechanism specified for your site; do not transfer these examples to a platform API with a different contract.
Two forms are useful: a raw body composed of the file bytes, or a multipart form with a part containing the file. Choose the form your client actually needs to produce. If the request reaches another server, the user lacks upload permission, or thumbnail generation fails after creation, the correction lies elsewhere.
Record what is sent and what responds
From the client or integration logs, find the failed attempt. Record the method, known final URL, HTTP status, and WordPress JSON code if present. Also note the declared body type and mode selected in the client. A 400 status without further details cannot determine whether a file was missing.
The browser’s Network tab can help if the upload originates from a page. For a server script, the client’s logging tool is more relevant. Do not export a raw request with its cookies, Authorization header, or user file. Make a targeted record using the control media and masked values.
- Check that the observed request is the creation POST, not a media-library GET.
- Record the status, error code field, and message, masking private data.
- Note whether the body is declared binary, JSON, or multipart and whether the sent size seems plausible.
- Identify the software or stage constructing the request: form, HTTP client, connector, or intermediary.
Confirm the correct URL and upload permission
Use the copy’s HTTPS address confirmed by its operator and the REST route it advertises. If WordPress is installed in a subdirectory or belongs to a network, verify the complete path and correct subsite. A redirect to a login page or another domain is a routing or access lead. Identify its destination before sending a secret; do not add automatic redirect following to the examples.
The identity used by the integration must have permission to upload files. If you attach the media to a post in the same request, WordPress also checks permission to edit that post. Avoid this field in the first test to separate file transport from content permissions. A refusal can appear under different statuses depending on stage and version; read its associated code and message.
An already logged-in browser and a remote script do not necessarily use the same authentication. For the script, the examples assume an application password authorized for the test account over HTTPS. Reuse neither your usual password nor another integration’s secret. If this mode is unavailable, use the approved mechanism on this copy.
Prepare a control file and an isolated first test
Choose a small, valid PNG image containing no personal data. Name it diagnostic-rest.png to follow the examples. Avoid an empty file, an extension changed without conversion, an image obtained from a third party, or a document intended for publication. Check that the client can read the local file and that the WordPress copy permits this type. The filename helps locate it, but the item ID distinguishes two attempts.
If you already have the appropriate permission, check the control upload once under Media, then Add New Media File, or through the media library’s add button depending on version. Success shows that the site can process the control through the interface; it does not prove that the integration’s account and protections are identical. If this control also fails through the interface, record the error before modifying the REST client.
Do not attach the control to a real post. Record items created through the interface and API so they can be removed at the end. If the immediate objective is merely adding a file and the interface works, it remains a temporary solution while diagnosing the connector.
Choose one format instead of combining JSON and a file
In a raw upload, the body contains file bytes from first to last. The client declares the content type and specifies the filename in Content-Disposition. A body containing the filename or a JSON string encoding its content does not reproduce this upload. The native controller expects a precise form; writing the local path in the body does not give it access to the client’s disk.
In multipart, the request contains separate parts. The file is a part named file, and the client generates boundaries and headers for each part. Some form fields can travel alongside the file, but the first test can be limited to file. Do not force the entire message’s header to image/png in this mode: only the file carries that type.
Choose binary if your integration already provides a byte stream. Choose multipart if its library can construct a form with a file. If it can produce only JSON, find its file-upload feature or change the client used for this stage. Do not alternate formats and authentication in the same test.
Repair a binary upload with the two expected headers
Run this example in a private sh-style terminal from the control file’s directory. Replace compte-api and the URL with the authorized copy’s values. The curl client is free software and requires no purchase or WordPress plugin. The --user option with only the username prompts for the secret in the terminal: enter the application password at that prompt. Do not add it after a colon in the command. The --disable option, placed first, avoids applying your account’s default curl configuration to this test.
The --data-binary argument reads the local file using @ and transmits its bytes. The two headers specify the actual type and filename to use. For another file, adapt the local path, proposed name, and declared type together. The example creates an item on the copy if successful; do not replay the command if the result is slow without first checking whether media was created.
With the native controller, expected complete success is HTTP 201 and a JSON object containing an ID. If curl says it cannot open the local file, correct the client-side path before interpreting a server error.
curl --disable --include --max-time 30 --user "compte-api" \
--header "Content-Type: image/png" \
--header 'Content-Disposition: attachment; filename="diagnostic-rest.png"' \
--data-binary "@diagnostic-rest.png" \
"https://preprod.example/wp-json/wp/v2/media"Repair a multipart form by attaching a file part
Use this example if the client declares a multipart form or the integration needs to attach a file and form fields. It runs on the same copy with a local control file. Do not run both examples by default: each creates an item if the upload succeeds. Compare them only if the transport difference needs isolating.
The --form option asks curl to construct the form. The @ prefix after file= means that the part contains the file read from disk. Without it, you may send the name as text. This part’s type parameter describes the image. Let curl produce the message’s multipart header and boundary. In another client, choose the file option for the file part and let its library construct the form in the same way.
If the upload succeeds, keep the status and ID to compare with the integration result. If curl succeeds but the usual client fails, compare the two requests with identical data: part name, type, actual body, and URL. Do not change server limits solely on the basis of this difference.
curl --disable --include --max-time 30 --user "compte-api" \
--form "file=@diagnostic-rest.png;type=image/png" \
"https://preprod.example/wp-json/wp/v2/media"Interpret the precise code before changing settings
The WordPress code helps determine how far processing progressed. Missing headers on a raw body are corrected in that request’s construction. For a multipart form, adding the same header to the entire message may mask a form-reading error: first check why no usable file part is recognized.
The server may return an HTML response or network error without a WordPress code. Then compare the URL, status, and receipt logs without concluding that the controller read the file. If several defects coexist, repair one stage and record the new result.
- For
rest_upload_no_data, confirm local reading and the presence of bytes or the file part at the receiving point. - For
rest_upload_no_content_type, check the raw body type; in multipart, first verify that the client correctly produced the form. - For
rest_upload_no_content_dispositionorrest_upload_invalid_disposition, check the raw-upload path for the header and a correct filename parameter. - For
rest_upload_hash_mismatch, compare the content actually received with the content used for the integrity calculation; do not disable a check required by the integration. - For an access or route refusal, correct the identity or address before assessing size and format.
Determine whether the file is lost before or after WordPress
If a correct request succeeds with a small file but fails with a larger one, record the body size and first layer rejecting it. A 413 response may come from the service in front of WordPress. For multipart uploads, PHP can also reject the file or entire body according to its effective limits. The form body includes more than just the image size. If the body exceeds post_max_size, PHP may leave its parsed fields and files empty; also compare upload_max_filesize and the site’s PHP-context log. These cases are not corrected by adding Content-Disposition.
Ask the owner to compare the time, URL, status, and client-observed size with logs from the first server and then PHP. A proxy or filter may also reject a request type on only one route. Have the precise rule corrected once identified without removing all API protection. If WordPress rejects the same file in both modes, read its type, quota, or write error and handle that cause separately.
Creation followed by image-processing failure is another case. The file or item may already exist while some sizes are not ready. Check the media library before changing the client or resending the same bytes.
Confirm creation, then check media use
Read the response status and body. For the native creation flow, HTTP 201 with an item ID is the expected result. In the same copy’s media library, find the item matching that ID and open the image through the intended flow. A site may store files on another service; check that the returned address or preview matches the expected storage. Do not assume the image should be publicly accessible if the environment is private.
A correct response does not validate every integration setting. If the connector must then populate the title, alternative text, or parent post, check those actions in a second stage using the obtained ID. Do not resend the file merely to edit its item text. The update route targets the existing ID.
- Record the test media’s ID and status.
- Check the item and file in the authorized media library.
- Correct the usual client and repeat a control check in the same context.
- Compare the result and verify that the integration retains the ID instead of creating a duplicate.
Return to the previous configuration without deleting the wrong media
If the client modification breaks a previously working flow, restore its backed-up version and repeat a read or authorized test on the copy. Configuration rollback does not erase media already written. After a timeout, the connection may have closed while writing or processing continued. Do not use automatic repetition as the first response to this uncertain state.
Search for test items by time, name, and ID. When an X-WP-Upload-Attachment-ID header is present, it may provide an ID to check even if subsequent processing failed. Its absence does not prove nothing was created. Distinguish the interface attempt from the API attempt.
On the copy, remove only confirmed test items through Media, then Library, checking that no content uses them. Permanent deletion may remove the associated file; do not use a bulk selection based only on similar names. Revoke the application password if you created it exclusively for this check. Do not touch integration access that must remain in service.
Document the expected format for future uploads
In the integration’s private documentation, record the destination URL per environment, method, body format, and expected headers. If using multipart, record the exact part name. If using a raw body, specify that the client sends bytes and that the declared name must match the actual type. Keep server-verified limits instead of inferring an allowed size from a single successful test.
The team can retain a small control file with no personal data and a checking procedure on an isolated copy. Track the ID returned by WordPress in technical traces without logging the access header or file content. Also define handling of ambiguous responses: check whether the media exists before resending the POST.
If the block persists, provide the maintainer with the time, status, error code, upload mode, size, and last point where the file is still observed. A reproducible comparison is more useful than a complete request copy. It identifies who needs to correct the client, authorization, or receiving layer.
Compare bytes before changing server limits
Prepare an acceptance-test sheet with the control filename, local size, raw or multipart mode, received status, and any created media ID. Keep one control throughout comparison. A total multipart size slightly larger than the file is normal: it includes boundaries and fields; it does not prove corruption.
If raw upload fails and multipart succeeds, compare body construction and headers. If both fail with the same access refusal, format is probably not the first stage to correct. If the small control succeeds but a larger valid file fails, ask for effective limits at the receiving point. A plugin changing the limits displayed in WordPress does not necessarily raise proxy or PHP limits.
For a connector developer, separate “create the file” from “complete its metadata.” As soon as the first POST returns an ID, retain it; a title or alternative-text change then uses that media item’s route. Do not replay the file to try to repair metadata.
The free native check in Media remains a temporary alternative for a user who only needs to upload the file. At the end, remove controls by their confirmed IDs and revoke only access created for the test. If a timeout leaves the state uncertain, check the media library before any new creation.
Sources and references
Use these references to check the features, requirements and limitations described. Reading documentation is not a practical test.
View 11 references
- WordPress: creating and reading REST media ↗
- WordPress: media controller code ↗
- WordPress: REST authentication and application passwords ↗
- PHP: processing files sent in multipart ↗
- PHP: body and upload limits ↗
- curl: transfer and form options ↗
- curl: license ↗
- curl: official logo ↗
- WordPress: receiving a raw body ↗
- WordPress: receiving multipart ↗
- WordPress: response after media creation ↗


