Categories About Us Contact Us Become a Member

How to fix E12505 Attachment content is invalid, only base64 or absolute URL is allowed

This is a Kaleyra Email API rejection meaning the content field of your attachment was neither base64 data nor a URL. Both forms are accepted, so you have two ways out. Jump to your situation below or work through the methods in order.

By Neeraj Singh ~11 min Updated Jul 2026 90% found this helpful
Error message
E12505  |  Invalid Input  |  parameter: attachment  |  "Attachment content is invalid, only base64 or absolute URL is allowed"
Summary

E12505 is an error from the Kaleyra Email API, returned with type Invalid Input and parameter: attachment. The message is specific and worth reading closely: Attachment content is invalid, only base64 or absolute URL is allowed. That sentence contains the whole fix, because Kaleyra accepts two forms in the attachment content field, and most people only know about one. You can pass base64-encoded data, or you can pass an absolute URL that points at the file and let Kaleyra fetch it. The error fires when content is neither: typically raw .eml text pasted straight in, a truncated or malformed base64 string or a relative path rather than a full URL. The fix is either to send the .eml as clean base64 read from the file in binary mode or to host it and pass the absolute URL. Set content_type and filename alongside it in both cases. Note that size problems are a different code, so if your file is large you are looking for E14512 or E14514 instead.

What E12505 is telling you

The Kaleyra Email API returns errors as a JSON object with a code, a type, the offending parameter and a message. E12505 arrives like this:

{
  "error": {
    "code": "E12505",
    "type": "Invalid Input",
    "parameter": "attachment",
    "message": "Attachment content is invalid, only base64 or absolute URL is allowed"
  }
}

It is a validation error, not a delivery failure. Kaleyra never accepted the request, so nothing was sent and there is no message ID. The API checked the content value inside your attachments array, found it was neither base64 data nor an absolute URL and stopped there.

Figure 1: the two forms Kaleyra accepts in content

Option A base64 data

  • Read the .eml as binary, then base64-encode the whole file.
  • Put the resulting string in content.
  • Best when the file is generated on the fly or is not publicly reachable.

Option B absolute URL

  • Host the .eml and put the full URL in content.
  • Kaleyra fetches the file, so no encoding on your side.
  • It must be absolute. A relative path fails.

Most guides only mention base64, which is why this error frustrates people who already know the file is fine. Read the message literally: only base64 or absolute URL is allowed. If encoding is awkward in your stack, the URL route is a legitimate fix rather than a workaround.

Figure 2: what passes and what triggers E12505
"content": "TWltZS1WZXJzaW9uOiAxLjANCg..."Valid. Base64 of the file's bytes.
"content": "https://example.com/files/message.eml"Valid. An absolute URL Kaleyra can fetch.
"content": "asfsvadvsdfsdfsdf"Rejected. Neither a URL nor decodable base64. This is Kaleyra's own example of the failure.
"content": "From: a@b.com\nSubject: Hi..."Rejected. Raw .eml text pasted straight in without encoding.
"content": "/files/message.eml"Rejected. A relative path is not an absolute URL.
"content": "TWltZS1WZXJzaW9uOiAxLjANCg"Rejected if truncated. A cut-off string will not decode.

The error names the offending field for you: the response carries parameter: attachment, so you are looking at the content value inside the attachments array and nothing else.

Common causes of E12505

The raw .eml text was placed in content without encoding it.
The content value is a relative path rather than an absolute URL.
The base64 string is truncated, so it cannot be decoded.
The file was read as text, which altered bytes before encoding.
A data URI prefix such as data:message/rfc822;base64, was left on the string.
The attachment object is missing content, or content is empty.
The URL is absolute but Kaleyra cannot reach it, for example it needs a login.
Line breaks or stray whitespace were introduced into the base64 value.
Expert insight

“Read the message, it is doing you a favour. It says only base64 or absolute URL is allowed, and that word or is the bit people miss. Half the tickets I see are someone fighting with encoding when they could have dropped a URL in and moved on. If you do encode, read the file as binary, not text, because reading an .eml as text is what quietly mangles it before you have even started. And do not chase this one for size. If your file is big you get a different code entirely, so a 20 MB attachment failing is not E12505.”

How to fix it

Method 1

Read the error and confirm the field

1Check the JSON response has "code": "E12505" with "parameter": "attachment". That confirms the fault is the attachment, not the recipients or the body.
2If the code is different, you have a different problem. Compare it against Figure 3.
3Print the exact content value you sent. In most cases the fault is obvious the moment you look at it.
Method 2

Decide: base64 or URL

1Kaleyra accepts either, so pick the one that suits your stack rather than assuming base64 is required.
2Choose base64 if the .eml is generated at runtime, is private or is not reachable over the internet.
3Choose an absolute URL if the file is already hosted somewhere Kaleyra can fetch it. It removes the encoding step entirely.
Method 3

Encode the .eml as base64 correctly

1Read the file in binary mode and encode the whole thing. Reading as text alters bytes and produces a payload that will not decode:
# Python
import base64
with open('message.eml','rb') as f:
    content = base64.b64encode(f.read()).decode('ascii')
2Other stacks:
// Node.js
const content = require('fs').readFileSync('message.eml').toString('base64');

# PHP
$content = base64_encode(file_get_contents('message.eml'));
3Send the raw string only. Strip any data:...;base64, prefix, because Kaleyra expects the encoded value on its own.
Method 4

Or pass an absolute URL

1Host the .eml and pass the full URL in content. It must include the scheme, so https://example.com/files/message.eml works and /files/message.eml does not.
2Make sure the URL is reachable without a login. If Kaleyra cannot fetch it, the content is not usable.
3This is a supported form, not a workaround. Kaleyra's own docs send an attachment this way.
Method 5

Get the attachment object right

1attachments is an array of objects, each with content, content_type and filename:
"attachments": [
  {
    "content": "TWltZS1WZXJzaW9uOiAxLjANCg...",
    "content_type": "message/rfc822",
    "filename": "message.eml"
  }
]
2For an .eml, message/rfc822 is the correct MIME type. Note that Kaleyra's docs show content_type in the working examples and content-type with a hyphen elsewhere, so if a request behaves oddly, try the underscore form first.
3Do not send the array as a JSON string. It must be a real array in the body.
Method 6

Verify the base64 decodes

1Before blaming the API, decode your own string and check you get the original file back:
# Round-trip check
base64 -d encoded.txt > check.eml
head -5 check.eml
2The output should start with real headers such as MIME-Version: or From:. If it errors or looks like noise, the encoding step is your fault, not Kaleyra's.
3Compare byte counts between the original and the decoded file to catch truncation.
Method 7

Test with a small known-good file

1Send a tiny plain-text attachment first to prove the request shape works, using Kaleyra's own example values.
2If the small file succeeds and your .eml fails, the request shape is fine and the problem is your encoding step or the URL.
3Then swap in the real .eml and compare what changed.

Do not chase size on this error. Kaleyra caps the whole request at 20 MB (text body plus html body plus attachments), and the body fields at 5 MB each, but breaching those limits returns E14514 Request payload exceeded or E14512 Attachment content exceeded limit, not E12505. If you are getting E12505, your payload is the wrong shape, not the wrong size, and shrinking the file will not help.

Make sure it is really E12505

Kaleyra returns several attachment-related codes and they are fixed in completely different ways. The code field in the JSON response tells you which one you have, so read it before you start changing anything.

Figure 3: E12505 against the codes it gets confused with
E12505: Attachment content is invalid, only base64 or absolute URL is allowed
MeansThe content field is neither base64 data nor an absolute URL. ActionYou are on the right page.
E12506: Unsupported file type, please upload valid files
MeansThe content decoded fine, but the file type is not accepted. ActionDifferent error. Check the file type you are attaching.
E14512: Attachment content exceeded limit
MeansThe attachment itself is too big. ActionDifferent error. Shrink the file or link to it.
E14514: Request payload exceeded
MeansThe whole request passed 20 MB, counting both bodies and attachments. ActionDifferent error. Reduce total payload.
E12515: From address(Sender domain) is not whitelisted
MeansThe sending domain was never enabled on the account. ActionDifferent error. Ask Kaleyra support to whitelist the domain.
E12500: Invalid input
MeansA generic validation failure elsewhere in the request. ActionDifferent error. Read the parameter field in the response.

There is a clean split worth remembering. E125xx codes are about the shape of what you sent, so the payload is malformed. E145xx codes are about limits, so the payload is well-formed but too big. Encoding fixes the first group and never fixes the second.

Frequently asked questions

What does E12505 mean?
It is a Kaleyra Email API validation error meaning the content field of your attachment is neither base64-encoded data nor an absolute URL. The full message reads: Attachment content is invalid, only base64 or absolute URL is allowed. The request is rejected, so nothing is sent.
Do I have to base64-encode the attachment?
No, and this is the most useful thing to know about E12505. Kaleyra accepts either base64 data or an absolute URL in the content field. If encoding is awkward in your stack, host the file and pass the full URL instead.
How do I base64-encode an .eml correctly?
Read the file in binary mode and encode the whole file, for example base64.b64encode(open('message.eml','rb').read()) in Python. Send the resulting string on its own, without any data URI prefix.
Why does reading the file as text break it?
Text mode applies character-set decoding and can rewrite line endings, so the bytes you encode are no longer the bytes in the file. The base64 then represents a different, damaged file. Always open the .eml in binary mode.
Can I pass a URL instead of base64?
Yes. The URL must be absolute, so it needs the scheme, as in https://example.com/files/message.eml. A relative path like /files/message.eml is rejected, and the URL has to be reachable by Kaleyra without a login.
Could the file size cause E12505?
No. Size limits return different codes: E14512 for an attachment that is too large, and E14514 when the whole request passes the 20 MB limit. E12505 is only about the shape of the content value, so shrinking the file will not clear it.
What content type should an .eml attachment use?
message/rfc822 is the correct MIME type for an email message file, set in the content_type field alongside content and filename. The content type does not cause E12505, but it matters for how the recipient's client handles the attachment.
How do I check my base64 is valid?
Decode it back and inspect the result. Piping it through base64 -d should reproduce the original file, starting with readable headers such as MIME-Version: or From:. Comparing byte counts also catches truncation.
What are the attachment fields called?
Each object in the attachments array uses content, content_type and filename. Kaleyra's docs show content_type in the working examples and a hyphenated content-type elsewhere, so prefer the underscore form if a request behaves unexpectedly.
Is E12505 a SendGrid or Mailgun error?
No. E12505 is specific to the Kaleyra Email API, which returns errors as a JSON object with code, type, parameter and message. Other providers report invalid attachments with their own formats and wording.

Still not working?

If a round-trip decode proves your base64 is sound and the request still returns E12505, log the exact bytes you are sending rather than the variable you think you are sending, because a serialiser quietly wrapping the array as a string is a common culprit. Sending the same file as an absolute URL is a fast way to isolate this: if the URL form works, the problem is your encoding path. The email channel also has to be enabled on the account with your sending domain whitelisted, so a brand-new account can fail for reasons unrelated to the attachment. You can also submit your error to us for a tailored fix.

Was this fix helpful? Thanks for your feedback!