apache/beam · error
Refusing to serve " + filePath + " as it is not under " +…
Error message
Refusing to serve " + filePath + " as it is not under " + rootDir
What it means
During artifact offering, the ArtifactsServiceHandler serving file artifacts normalizes the requested artifact path and refuses to serve any file that resolves outside the configured rootDir. This is a deliberate security guard against path traversal: the runner should only ever serve artifacts staged under its own artifact root.
Solutions
- Ensure the artifact staging root passed as rootDir matches the directory where artifacts were actually staged.
- Fix the artifact payload paths so they are relative to (or inside) rootDir before offering artifacts.
- Check environment/config that determines the staging directory (temp dir, --artifacts_dir equivalent) so both sides agree.
- If intentionally serving from elsewhere, reconfigure the handler's rootDir to include that location (after verifying it is safe).
Defensive patterns
Strategy: validation
Validate before calling
// before offering
const normalized = path.normalize(artifactPath);
if (!normalized.startsWith(rootDir)) {
console.error('Artifact outside staging root:', normalized);
} Try / catch
try {
await handler.offerArtifacts(...);
} catch (e) {
if ((e as Error).message.includes('Refusing to serve')) {
// re-stage artifacts under the expected root, then retry once
} else throw e;
} Prevention
- Always stage artifacts inside the directory passed as rootDir.
- Use relative paths in artifact payloads where possible.
- Keep the staging root consistent across job service and runner config.
- Never accept user-supplied absolute artifact paths.
When it happens
Trigger: The runner proxy receives a beam:artifact:type:file:v1 request whose ArtifactFilePayload.path normalizes to a path that does not start with rootDir (e.g. '/etc/passwd' or '../secrets' or a path staged elsewhere on disk).
Common situations: Artifact staging directory misconfigured (rootDir doesn't match where the job service actually staged files); artifacts built in a different temp directory than the one handed to the handler; a malicious or buggy job submitting absolute paths.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Cannot unzip file containing an entry with ".." in the…
- error validating file path
- file path is outside destination directory
- Unknown artifact type " +…
- Unknown request type " + msg.request.oneofKind
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/797b1fada68412a8.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/typescript/src/apache_beam/runners/artifacts.ts:145
isLast: false,
response: {
oneofKind: "resolveArtifactResponse",
resolveArtifactResponse: {
replacements: msg.request.resolveArtifact.artifacts,
},
},
});
break;
case "getArtifact":
switch (msg.request.getArtifact.artifact!.typeUrn) {
case "beam:artifact:type:file:v1":
const payload = runnerApi.ArtifactFilePayload.fromBinary(
msg.request.getArtifact.artifact!.typePayload,
);
const filePath = path.normalize(payload.path);
if (!filePath.startsWith(rootDir)) {
throw new Error(
"Refusing to serve " +
filePath +
" as it is not under " +
rootDir,
);
}
const handle = fs.createReadStream(filePath);
for await (const chunk of handle) {
call.requests.send({
stagingToken: stagingToken,
isLast: false,
response: {
oneofKind: "getArtifactResponse",
getArtifactResponse: { data: chunk },
},
});
}
call.requests.send({View on GitHub (pinned to 12126d8942)