[GH-ISSUE #463] Suggestion: Don't change Message-ID to Message-Id #298

Closed
opened 2026-03-15 13:46:21 +03:00 by kerem · 7 comments
Owner

Originally created by @ThomasLandauer on GitHub (Mar 12, 2025).
Original GitHub issue: https://github.com/axllent/mailpit/issues/463

Am I right that you're converting the Message-ID: header's name to Message-Id:?

According to RFC 5322, the name is Message-ID, so I'm suggesting that you don't change it.

Originally created by @ThomasLandauer on GitHub (Mar 12, 2025). Original GitHub issue: https://github.com/axllent/mailpit/issues/463 Am I right that you're converting the `Message-ID:` header's name to `Message-Id:`? According to [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.6.4), the name is `Message-ID`, so I'm suggesting that you don't change it.
kerem closed this issue 2026-03-15 13:46:26 +03:00
Author
Owner

@axllent commented on GitHub (Mar 12, 2025):

Am I right that you're converting the Message-ID: header's name to Message-Id:?

Hi @ThomasLandauer - can you please be a bit more specific where exactly you are meaning? Mailpit adds a Message-Id (I note your point below) if there is none, and it overwrites the Message-Id when releasing mail, however other than that it doesn't convert any of them as far as I can recall.

According to RFC 5322, the name is Message-ID, so I'm suggesting that you don't change it.

Yes, you are correct, I will look into this. Before I do though, could you please provide more info to my question above? Thanks.

<!-- gh-comment-id:2718961382 --> @axllent commented on GitHub (Mar 12, 2025): > Am I right that you're converting the `Message-ID:` header's name to `Message-Id:`? Hi @ThomasLandauer - can you please be a bit more specific where exactly you are meaning? Mailpit adds a `Message-Id` (I note your point below) if there is none, and it overwrites the `Message-Id` when releasing mail, however other than that it doesn't convert any of them as far as I can recall. > According to [RFC 5322](https://datatracker.ietf.org/doc/html/rfc5322#section-3.6.4), the name is `Message-ID`, so I'm suggesting that you don't change it. Yes, you are correct, I will look into this. Before I do though, could you please provide more info to my question above? Thanks.
Author
Owner

@ThomasLandauer commented on GitHub (Mar 12, 2025):

When an incoming message contains this header:

Message-ID: <123@example.com>

In Mailpit's web interface, when I click the "Headers" tab, I see Message-Id. And when requesting this info via an API call, I think it has to be requested as Message-Id.

<!-- gh-comment-id:2719007317 --> @ThomasLandauer commented on GitHub (Mar 12, 2025): When an incoming message contains this header: ``` Message-ID: <123@example.com> ``` In Mailpit's web interface, when I click the "Headers" tab, I see `Message-Id`. And when requesting this info via an API call, I think it has to be requested as `Message-Id`.
Author
Owner

@axllent commented on GitHub (Mar 13, 2025):

Oh I see what you mean. Hmm, this is a tough one because those headers are extracted & grouped via another package. Given that there can easily be inconsistency in the header casing (even within the same message), these header keys are programmatically Pascal-cased (ie: mesSaGe-iD becomes Message-Id). You'd be surprised how many Message-Id instead of Message-ID, CC instead of Cc, BCC instead of Bcc headers there are, so strict parsing (which no system does) would break many, many messages.

Whilst I'm sure I could potentially modify some of these before returning the information via the API, changing this type of behavior would also potentially break other existing integrations which test for Message-Id in headers response. So, whilst I totally get your point (and you're not wrong), I can't change do that.

I can however ensure better consistency when overwriting or adding a Message-ID header (via mailpit sendmail & releasing messages) which your point made me realise.

<!-- gh-comment-id:2719440979 --> @axllent commented on GitHub (Mar 13, 2025): Oh I see what you mean. Hmm, this is a tough one because those headers are extracted & grouped via another package. Given that there can easily be inconsistency in the header casing (even within the same message), these header keys are programmatically Pascal-cased (ie: `mesSaGe-iD` becomes `Message-Id`). You'd be surprised how many `Message-Id` instead of `Message-ID`, `CC` instead of `Cc`, `BCC` instead of `Bcc` headers there are, so strict parsing (which no system does) would break many, many messages. Whilst I'm sure I could potentially modify some of these before returning the information via the API, changing this type of behavior would also potentially break other existing integrations which test for `Message-Id` in headers response. So, whilst I totally get your point (and you're not wrong), I can't change do that. I can however ensure better consistency when overwriting or adding a `Message-ID` header (via `mailpit sendmail` & releasing messages) which your point made me realise.
Author
Owner

@ThomasLandauer commented on GitHub (Mar 13, 2025):

I'm not surprised - that's why I don't suggest strict parsing ;-)

But you have to be aware: If you parse a message with Message-ID and present it as Message-Id, you're kind of telling people that this would be the correct/recommended casing.

As far as I see, Message-ID is the only affected header. So what you could do is just relabel this one (from the other package's output).

If possible, keep Message-Id as alias (for backwards compatibility), but raise some deprecation note somewhere.

<!-- gh-comment-id:2719468045 --> @ThomasLandauer commented on GitHub (Mar 13, 2025): I'm not surprised - that's why I don't suggest strict *parsing* ;-) But you have to be aware: If you parse a message with `Message-ID` and present it as `Message-Id`, you're kind of telling people that this would be the correct/recommended casing. As far as I see, `Message-ID` is the only affected header. So what you could do is just relabel this one (from the other package's output). If possible, keep `Message-Id` as alias (for backwards compatibility), but raise some deprecation note somewhere.
Author
Owner

@axllent commented on GitHub (Mar 13, 2025):

But you have to be aware: If you parse a message with Message-ID and present it as Message-Id, you're kind of telling people that this would be the correct/recommended casing.

Absolutely, I understand exactly what you are saying, although I wouldn't fully agree on this being used as a source of truth. The message(s) API returns the Message-ID as MessageID, and that doesn't tell people it should actually be called that.

As it currently stands, these headers are currently a 1:1 output of the default (built-in) mail parsing package within Go.

As far as I see, Message-ID is the only affected header. So what you could do is just relabel this one (from the other package's output).

To further my point, headers such as List-ID => List-Id, ARC-Message-Signature => Arc-Message-Signature, DKIM-Signature => Dkim-Signature, X-TUID => X-Tuid - they all are rewritten in the exact same (but consistent) manner as Message-ID

If possible, keep Message-Id as alias (for backwards compatibility), but raise some deprecation note somewhere.

I honestly do not feel I can (or should) do something special to change (or duplicate) Message-Id. I do agree with you, it's not what the RFC says, but there is a consistency between all these headers, and if I was to change one, then I should change them all (except I'll never get them all), and adding a duplicate header field will also appear like the Message-Id and Message-ID is duplicated in the header (which is even more misleading).

Do you understand my point?

<!-- gh-comment-id:2719658059 --> @axllent commented on GitHub (Mar 13, 2025): > But you have to be aware: If you parse a message with `Message-ID` and present it as `Message-Id`, you're kind of telling people that this would be the correct/recommended casing. Absolutely, I understand exactly what you are saying, although I wouldn't fully agree on this being used as a source of truth. The message(s) API returns the `Message-ID` as `MessageID`, and that doesn't tell people it should actually be called that. As it currently stands, these headers are currently a 1:1 output of the default (built-in) mail parsing package within Go. > > As far as I see, `Message-ID` is the only affected header. So what you could do is just relabel this one (from the other package's output). To further my point, headers such as `List-ID` => `List-Id`, `ARC-Message-Signature` => `Arc-Message-Signature`, `DKIM-Signature` => `Dkim-Signature`, `X-TUID` => `X-Tuid` - they all are rewritten in the exact same (but consistent) manner as `Message-ID` > If possible, keep `Message-Id` as alias (for backwards compatibility), but raise some deprecation note somewhere. I honestly do not feel I can (or should) do something special to change (or duplicate) `Message-Id`. I do agree with you, it's not what the RFC says, but there is a consistency between all these headers, and if I was to change one, then I should change them all (except I'll never get them all), and adding a duplicate header field will also appear like the `Message-Id` and `Message-ID` is duplicated in the header (which is even more misleading). Do you understand my point?
Author
Owner

@ThomasLandauer commented on GitHub (Mar 13, 2025):

Yeah, sure I understand.

Maybe you could open an issue at Go - maybe they have an idea? (I would open it myself if I had any knowledge of Go...)

<!-- gh-comment-id:2720871919 --> @ThomasLandauer commented on GitHub (Mar 13, 2025): Yeah, sure I understand. Maybe you could open an issue at Go - maybe they have an idea? (I would open it myself if I had any knowledge of Go...)
Author
Owner

@axllent commented on GitHub (Mar 14, 2025):

I believe that anyone requesting a change to the default behavior would likely be denied. As I mentioned earlier, Go consistently returns all headers, regardless of their nature. While the casing of the Message-ID field may not comply with RFC standards, it’s important to note that it was never claimed to be RFC-compliant. The same applies to Mailpit's header responses; these are simply JSON object keys used to reference their values. If you need the Message-ID, you should use Message-Id in your automation. Altering the casing in the web UI could also create confusion for developers looking to integrate with the API and using the web UI as a reference.

Additionally, Message-Id is actually very commonly used (and thus supported), regardless of RFC specifications. I checked my personal emails and found that 35,502 out of 132,393 (27%) use Message-Id instead of Message-ID.

I appreciate your input, but I won’t be pursuing this further, as the drawbacks of making this change far outweigh any potential benefits.

<!-- gh-comment-id:2723506398 --> @axllent commented on GitHub (Mar 14, 2025): I believe that anyone requesting a change to the default behavior would likely be denied. As I mentioned earlier, Go consistently returns all headers, regardless of their nature. While the casing of the `Message-ID` field may not comply with RFC standards, it’s important to note that it was never claimed to be RFC-compliant. The same applies to Mailpit's header responses; these are simply JSON object **keys** used to reference their values. If you need the `Message-ID`, you should use `Message-Id` in your automation. Altering the casing in the web UI could also create confusion for developers looking to integrate with the API and using the web UI as a reference. Additionally, `Message-Id` is actually very commonly used (and thus supported), regardless of RFC specifications. I checked my personal emails and found that 35,502 out of 132,393 (27%) use Message-Id instead of Message-ID. I appreciate your input, but I won’t be pursuing this further, as the drawbacks of making this change far outweigh any potential benefits.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/mailpit#298
No description provided.