blob: 686564afbd8c59b362461d4bab2f9624e00d61e2 [file]
---
title: Exchange header naming conventions
authors:
- "@oscerd"
- "@gnodet"
reviewers: []
approvers: []
creation-date: 2026-05-22
last-updated: 2026-05-22
status: implementable
see-also: []
replaces: []
superseded-by: []
---
== Summary
This document defines the naming conventions for Apache Camel Exchange headers.
All component headers must follow these rules so that header names are
predictable, self-documenting, and compatible with the framework's
`HeaderFilterStrategy` security mechanism.
== Motivation
Camel has 300+ components, many contributed independently over 15+ years.
Without a written standard, header string values drifted into at least four
different styles: `dns.name`, `QUERY`, `operationName`, `kafka.PARTITION_KEY`.
This inconsistency causes:
* Confusion for users who must memorize per-component formats.
* Security gaps: `DefaultHeaderFilterStrategy` strips `Camel*` headers
case-insensitively. Headers that don't use the `Camel` prefix bypass this
filter, which matters when untrusted input flows through the Exchange
(see link:security.adoc[]).
* Tooling friction: code generators, catalog introspection, and IDE completion
work best when header names follow a single predictable pattern.
== Convention
=== Header string values
Every component-owned Exchange header string value MUST follow:
----
"Camel" + ComponentName + Feature
----
All segments are PascalCase, concatenated without separators.
[cols="1,1,1", options="header"]
|===
| Component | Java constant | String value
| camel-kafka
| `KafkaConstants.TOPIC`
| `CamelKafkaTopic`
| camel-file
| `FileConstants.FILE_NAME`
| `CamelFileName`
| camel-jira
| `JiraConstants.ISSUE_KEY`
| `CamelJiraIssueKey`
| camel-pdf
| `PdfHeaderConstants.PDF_DOCUMENT_HEADER_NAME`
| `CamelPdfDocument`
|===
*ComponentName* is the PascalCase form of the Camel component scheme
(e.g., `kafka` -> `Kafka`, `elasticsearch` -> `Elasticsearch`,
`aws2-s3` -> `Aws2S3`).
=== Core framework headers
Headers defined in `org.apache.camel.Exchange` use the `Camel` prefix directly
(no component name), because they are framework-wide:
----
CamelFileName, CamelHttpResponseCode, CamelBatchSize, ...
----
=== Java constant names
Java constant field names use `UPPER_SNAKE_CASE`:
[source,java]
----
public static final String ISSUE_KEY = "CamelJiraIssueKey";
----
The constant name describes the concept; the string value encodes the
component namespace.
=== Constants class
Each component declares its header constants in a dedicated class:
----
<ComponentName>Constants.java
----
located in the component's main package
(`org.apache.camel.component.<name>`).
Each constant MUST carry an `@Metadata` annotation:
[source,java]
----
@Metadata(description = "The issue key", javaType = "String")
public static final String ISSUE_KEY = "CamelJiraIssueKey";
----
The `@Metadata` annotation drives automatic documentation generation (component
doc pages, catalog JSON, Endpoint DSL).
=== Header prefix constants
Some components use prefix-based headers (e.g., `CamelSolrField.title`,
`CamelSolrParam.rows`). The prefix constant follows the same convention:
[source,java]
----
public static final String HEADER_FIELD_PREFIX = "CamelSolrField.";
----
=== Protocol and standard headers
Headers that are part of an external wire protocol or standard (HTTP headers,
JMS properties, Swift API headers, etc.) are *exempt* from the `Camel` prefix
rule. They use the standard's own name because the framework passes them
through to the underlying transport.
Examples:
* Swift: `X-Container-Meta-`, `X-Versions-Location`
* HTTP: `Content-Type`, `Accept`
* JMS: standard JMS property names
When a component has both Camel-convention headers and protocol pass-through
headers, document the distinction clearly (see `camel-openstack` Swift
constants for an example).
=== Exchange properties
Exchange *properties* (set via `Exchange.setProperty()`) are internal to the
route and are NOT visible to `HeaderFilterStrategy`. They do not require the
`Camel` prefix, though many core properties use it by convention.
== Security interaction
The `Camel*` prefix is not just cosmetic. `DefaultHeaderFilterStrategy`
strips headers matching `Camel*` and `org.apache.camel.*` case-insensitively
from inbound messages. This prevents untrusted external senders from injecting
Camel-internal routing directives.
When a component header does *not* use the `Camel` prefix, it bypasses this
security filter entirely. This is why aligning all component headers to the
`Camel*` namespace is both a consistency improvement and a security hardening
measure.
See the link:security.adoc[] design document and the
xref:ROOT:security-model.adoc[] for the full threat model.
== Renaming existing headers
When renaming a non-conforming header to follow this convention:
=== What to change
1. Update the string value in the constants class.
2. Regenerate all downstream artifacts:
- `mvn install -pl <module> -DskipTests`
- `mvn install -pl catalog/camel-catalog -DskipTests`
- `mvn generate-sources -pl dsl/camel-endpointdsl -DskipTests`
- `mvn generate-sources -pl dsl/camel-componentdsl -DskipTests`
3. Update documentation (`.adoc` files, Javadoc) to reference the new names.
4. Update tests to use the Java constants (not literal strings).
=== Upgrade guide
Every header rename is a breaking change and MUST be documented in the upgrade
guide (`docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_XX.adoc`):
* List every old value -> new value.
* Note which Endpoint DSL method names changed.
* State that code using the Java constants is unaffected.
* Warn that code using literal string header names must be updated.
=== Backward compatibility
The project's current policy (as of 4.21) is a *hard break* with no deprecated
aliases. The Java constant names stay the same, so code using constants compiles
and works without changes. But code using literal header strings (XML/YAML
routes, Simple expressions, tests with hardcoded strings) will silently stop
matching.
This trade-off favors a clean, consistent header namespace over a gradual
migration. The upgrade guide is the primary migration aid.
=== Backport policy
When a header rename is backported to a maintenance branch (e.g.,
`camel-4.22.x`, `camel-4.18.x`):
* Add an upgrade guide entry on the maintenance branch.
* Also add the corresponding entry on `main` to keep the version-specific
upgrade guides in sync (see backport upgrade-guide policy in the project
contribution guidelines).
== Scope
This convention applies to:
* All new components (mandatory).
* Existing components when headers are modified for any reason (opportunistic
alignment).
* Dedicated alignment PRs (the ongoing CAMEL-2357x/CAMEL-2359x effort).
Headers in core (`Exchange.java`) already follow the convention and are not
being renamed.