{"record":{"id":"250e9305726e5f58","repo":"apache/seatunnel","slug":"stream-load-failed","errorCode":"STREAM_LOAD_FAILED","errorMessage":"stream load redirect not followed: HTTP/1.1 307 Temporary Redirect, request=<requestUrl>, Location=<location>, direct_to_be=<directToBe>, 2pc=<enable2PC>, stage=commit. Please check BE reachability, FE load, and consider benodes + direct_to_be=true when FE redirect is unstable.","messagePattern":"stream load redirect not followed: HTTP/1\\.1 307 Temporary Redirect, request=<requestUrl>, Location=<location>, direct_to_be=<directToBe>, 2pc=<enable2PC>, stage=commit\\. Please check BE reachability, FE load, and consider benodes \\+ direct_to_be=true when FE redirect is unstable\\.","errorType":"error_code","errorClass":"DorisConnectorException","httpStatus":307,"severity":"critical","filePath":"seatunnel-connectors-v2/connector-doris/src/main/java/org/apache/seatunnel/connectors/doris/sink/committer/DorisCommitter.java","lineNumber":135,"sourceCode":"                                dorisSinkConfig.getEnable2PC(),\n                                \"commit\");\n            } catch (DorisConnectorException e) {\n                lastRedirectException = e;\n                log.error(\"commit transaction redirect follow-up failed on {}: \", hostPort, e);\n                sleepBeforeNextAttempt(attempt);\n                continue;\n            } catch (IOException e) {\n                lastIOException = e;\n                log.error(\"commit transaction failed on {}: \", hostPort, e);\n                sleepBeforeNextAttempt(attempt);\n                continue;\n            }\n            try (CloseableHttpResponse closeableResponse = response) {\n                int statusCode = closeableResponse.getStatusLine().getStatusCode();\n                reasonPhrase = closeableResponse.getStatusLine().getReasonPhrase();\n                if (statusCode == HTTP_TEMPORARY_REDIRECT) {\n                    Header location = closeableResponse.getFirstHeader(\"Location\");\n                    throw new DorisConnectorException(\n                            DorisConnectorErrorCode.STREAM_LOAD_FAILED,\n                            DorisRedirectExceptionBuilder.build(\n                                    requestUrl,\n                                    location == null ? null : location.getValue(),\n                                    dorisSinkConfig.isDirectToBe(),\n                                    dorisSinkConfig.getEnable2PC(),\n                                    \"commit\"));\n                }\n                if (statusCode != HTTP_OK) {\n                    log.warn(\"commit failed with {}, reason {}\", hostPort, reasonPhrase);\n                    sleepBeforeNextAttempt(attempt);\n                    continue;\n                }\n                handleCommitSuccess(committable, hostPort, closeableResponse);\n                return;\n            }\n        }\n","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/apache/seatunnel/blob/cf67b549a7a6c35fa0beb12d83c62892427ea919/seatunnel-connectors-v2/connector-doris/src/main/java/org/apache/seatunnel/connectors/doris/sink/committer/DorisCommitter.java#L117-L153","documentation":"DorisCommitter.commitTransaction treats an HTTP 307 Temporary Redirect at commit stage as fatal because the HTTP client is configured not to follow redirects. The exception (built by DorisRedirectExceptionBuilder) includes the request URL, Location header, direct_to_be flag and 2PC flag, hinting that the BE is unreachable via the redirect or that FE redirect behavior is unstable.","triggerScenarios":"Stream-load commit POST to FE which responds 307 redirecting to a BE host the client cannot reach; dorisSinkConfig.isDirectToBe() is false; BE behind NAT/load balancer that rewrites the Location host; mixed network zones (container/K8s) where FE-advertised BE addresses aren't routable.","commonSituations":"Docker/Kubernetes deployments where BE registers with internal hostnames; FE returning unreachable BE nodes in Location; firewalls blocking the BE http port (8040); Doris versions where FE 307 redirect handling changed.","solutions":["Set `direct_to_be = true` in the Doris sink config to send stream-load directly to BE and skip FE redirects","Make FE-advertised BE addresses reachable (configure be http port, priority_networks, or DNS/hosts entries)","Use `benodes` option listing reachable BE addresses","Ensure firewall allows the BE HTTP port from the SeaTunnel nodes; retry commit"],"exampleFix":"// before\nDoris {\n  node-addresses = \"fe-host:8030\"\n}\n// after\nDoris {\n  node-addresses = \"fe-host:8030,be1:8040,be2:8040\"\n  direct_to_be = true\n}","handlingStrategy":"fallback","validationCode":"// precheck: curl -I the FE stream-load endpoint and confirm BE hosts in Location are reachable from SeaTunnel nodes\n// nc -z be-host 8040","typeGuard":null,"tryCatchPattern":"try {\n    committer.commit(committable);\n} catch (DorisConnectorException e) {\n    if (e.getErrorCode() == DorisConnectorErrorCode.STREAM_LOAD_FAILED && e.getMessage().contains(\"307\")) {\n        // fall back to direct-to-BE config or reachable benodes, then retry\n    }\n}","preventionTips":["Set direct_to_be = true in K8s/NAT environments","Configure benodes with BE addresses reachable from SeaTunnel nodes","Fix priority_networks so BE advertises routable IPs","Open the BE HTTP port (8040) in firewalls"],"tags":["http","redirect","doris","stream-load","network"],"backgroundTag":"http-307-redirect-not-followed","analyzedSha":"cf67b549a7a6c35fa0beb12d83c62892427ea919","analyzedAt":"2026-09-10T21:44:55.265Z","contentChangedAt":"2026-09-10T21:44:55.265Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}