This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch fix/camel-23345-http-429-docs in repository https://gitbox.apache.org/repos/asf/camel.git
commit 316d14086f4ea6842bf91489450055162f024697 Author: Claus Ibsen <[email protected]> AuthorDate: Mon May 18 20:50:02 2026 +0200 CAMEL-23345: Document HTTP 429 Retry-After hang and automaticRetriesDisabled workaround Adds a new section to the HTTP component docs explaining that Apache HttpClient 5 (since 5.5.x) honors the Retry-After header on 429 responses, which can cause the component to appear hung for long durations. Documents the automaticRetriesDisabled option as the workaround. Also improves the @Metadata description of automaticRetriesDisabled to mention the 429 use case. Co-Authored-By: Claude Sonnet 4.6 <[email protected]> --- .../org/apache/camel/catalog/components/http.json | 2 +- .../org/apache/camel/catalog/components/https.json | 2 +- .../org/apache/camel/component/http/http.json | 2 +- .../org/apache/camel/component/http/https.json | 2 +- .../camel-http/src/main/docs/http-component.adoc | 27 ++++++++++++++++++++++ .../apache/camel/component/http/HttpComponent.java | 5 +++- 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/http.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/http.json index 0e225986b037..6b5caa3b9291 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/http.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/http.json @@ -41,7 +41,7 @@ "userAgent": { "index": 11, "kind": "property", "displayName": "User Agent", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set a custom HTTP User-Agent request header" }, "allowJavaSerializedObject": { "index": 12, "kind": "property", "displayName": "Allow Java Serialized Object", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "security": "insecure:serialization", "defaultValue": false, "description": "Whether to allow java serialization when a request uses context-type=application\/x-java-serialized-object. This is by default turned off. [...] "authCachingDisabled": { "index": 13, "kind": "property", "displayName": "Auth Caching Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables authentication scheme caching" }, - "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution" }, + "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution. This is useful when a server responds with HTTP 429 (Too Many Requests) and includes a long Retry-After header, which would ot [...] "autowiredEnabled": { "index": 15, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching [...] "clientConnectionManager": { "index": 16, "kind": "property", "displayName": "Client Connection Manager", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.hc.client5.http.io.HttpClientConnectionManager", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom and shared HttpClientConnectionManager to manage connections. If this has been configured then this is always used for all endpoints created [...] "connectionsPerRoute": { "index": 17, "kind": "property", "displayName": "Connections Per Route", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 20, "description": "The maximum number of connections per route." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/https.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/https.json index e1c5eb558c23..e3ec05d138ea 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/https.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/https.json @@ -41,7 +41,7 @@ "userAgent": { "index": 11, "kind": "property", "displayName": "User Agent", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set a custom HTTP User-Agent request header" }, "allowJavaSerializedObject": { "index": 12, "kind": "property", "displayName": "Allow Java Serialized Object", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "security": "insecure:serialization", "defaultValue": false, "description": "Whether to allow java serialization when a request uses context-type=application\/x-java-serialized-object. This is by default turned off. [...] "authCachingDisabled": { "index": 13, "kind": "property", "displayName": "Auth Caching Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables authentication scheme caching" }, - "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution" }, + "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution. This is useful when a server responds with HTTP 429 (Too Many Requests) and includes a long Retry-After header, which would ot [...] "autowiredEnabled": { "index": 15, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching [...] "clientConnectionManager": { "index": 16, "kind": "property", "displayName": "Client Connection Manager", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.hc.client5.http.io.HttpClientConnectionManager", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom and shared HttpClientConnectionManager to manage connections. If this has been configured then this is always used for all endpoints created [...] "connectionsPerRoute": { "index": 17, "kind": "property", "displayName": "Connections Per Route", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 20, "description": "The maximum number of connections per route." }, diff --git a/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/http.json b/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/http.json index 0e225986b037..6b5caa3b9291 100644 --- a/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/http.json +++ b/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/http.json @@ -41,7 +41,7 @@ "userAgent": { "index": 11, "kind": "property", "displayName": "User Agent", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set a custom HTTP User-Agent request header" }, "allowJavaSerializedObject": { "index": 12, "kind": "property", "displayName": "Allow Java Serialized Object", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "security": "insecure:serialization", "defaultValue": false, "description": "Whether to allow java serialization when a request uses context-type=application\/x-java-serialized-object. This is by default turned off. [...] "authCachingDisabled": { "index": 13, "kind": "property", "displayName": "Auth Caching Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables authentication scheme caching" }, - "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution" }, + "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution. This is useful when a server responds with HTTP 429 (Too Many Requests) and includes a long Retry-After header, which would ot [...] "autowiredEnabled": { "index": 15, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching [...] "clientConnectionManager": { "index": 16, "kind": "property", "displayName": "Client Connection Manager", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.hc.client5.http.io.HttpClientConnectionManager", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom and shared HttpClientConnectionManager to manage connections. If this has been configured then this is always used for all endpoints created [...] "connectionsPerRoute": { "index": 17, "kind": "property", "displayName": "Connections Per Route", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 20, "description": "The maximum number of connections per route." }, diff --git a/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/https.json b/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/https.json index e1c5eb558c23..e3ec05d138ea 100644 --- a/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/https.json +++ b/components/camel-http/src/generated/resources/META-INF/org/apache/camel/component/http/https.json @@ -41,7 +41,7 @@ "userAgent": { "index": 11, "kind": "property", "displayName": "User Agent", "group": "producer (advanced)", "label": "producer,advanced", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "To set a custom HTTP User-Agent request header" }, "allowJavaSerializedObject": { "index": 12, "kind": "property", "displayName": "Allow Java Serialized Object", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "security": "insecure:serialization", "defaultValue": false, "description": "Whether to allow java serialization when a request uses context-type=application\/x-java-serialized-object. This is by default turned off. [...] "authCachingDisabled": { "index": 13, "kind": "property", "displayName": "Auth Caching Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables authentication scheme caching" }, - "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution" }, + "automaticRetriesDisabled": { "index": 14, "kind": "property", "displayName": "Automatic Retries Disabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Disables automatic request recovery and re-execution. This is useful when a server responds with HTTP 429 (Too Many Requests) and includes a long Retry-After header, which would ot [...] "autowiredEnabled": { "index": 15, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching [...] "clientConnectionManager": { "index": 16, "kind": "property", "displayName": "Client Connection Manager", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.hc.client5.http.io.HttpClientConnectionManager", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom and shared HttpClientConnectionManager to manage connections. If this has been configured then this is always used for all endpoints created [...] "connectionsPerRoute": { "index": 17, "kind": "property", "displayName": "Connections Per Route", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 20, "description": "The maximum number of connections per route." }, diff --git a/components/camel-http/src/main/docs/http-component.adoc b/components/camel-http/src/main/docs/http-component.adoc index 9a45aad4f75e..b81a7c8591b5 100644 --- a/components/camel-http/src/main/docs/http-component.adoc +++ b/components/camel-http/src/main/docs/http-component.adoc @@ -95,6 +95,33 @@ The option, `throwExceptionOnFailure`, can be set to `false` to prevent the `HttpOperationFailedException` from being thrown for failed response codes. This allows you to get any response from the remote server. +=== Handling HTTP 429 Too Many Requests + +When a server responds with HTTP 429 (Too Many Requests) and includes a +`Retry-After` header, the underlying Apache HttpClient 5 will automatically +wait for the specified duration before retrying the request. If the server +returns a long retry delay (for example, `Retry-After: 3600` for one hour), +the HTTP component will appear to hang for that duration. + +To avoid this, you can disable automatic retries on the component: + +[source,java] +---- +HttpComponent httpComponent = context.getComponent("https", HttpComponent.class); +httpComponent.setAutomaticRetriesDisabled(true); +---- + +Or as a URI option on the endpoint: + +[source,text] +---- +https://myhost/mypath?automaticRetriesDisabled=true +---- + +With automatic retries disabled, a 429 response is treated as an error and +a `HttpOperationFailedException` is thrown immediately (unless +`throwExceptionOnFailure=false`). + === Exceptions `HttpOperationFailedException` exception contains the following information: diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java index 38c8ed85d50e..755f6e564672 100644 --- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java +++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpComponent.java @@ -177,7 +177,10 @@ public class HttpComponent extends HttpCommonComponent implements RestProducerFa protected int responsePayloadStreamingThreshold = 8192; @Metadata(label = "advanced", description = "Disables automatic redirect handling") protected boolean redirectHandlingDisabled; - @Metadata(label = "advanced", description = "Disables automatic request recovery and re-execution") + @Metadata(label = "advanced", + description = "Disables automatic request recovery and re-execution." + + " This is useful when a server responds with HTTP 429 (Too Many Requests) and includes a long Retry-After header," + + " which would otherwise cause the client to wait (and appear to hang) before retrying.") protected boolean automaticRetriesDisabled; @Metadata(label = "advanced", description = "Disables automatic content decompression") protected boolean contentCompressionDisabled;
