hcengineering/platform · error · ApiError
Cannot process provided link
Error message
Cannot process provided link
What it means
The /print endpoint only renders links whose protocol is http: or https: and, when a hostname whitelist is configured for the server (allowedHostnames), whose hostname is in that whitelist. Any other link is rejected with this 403 ApiError. This is an SSRF / access-control guard, not a formatting problem.
Source
Thrown at services/print/pod-print/src/server.ts:214
app.use(cors())
app.use(express.json())
app.use(withMeasureContext({ ctx: measureCtx }))
app.get(
'/print',
wrapRequest(async (req, res, wsIds, wsLoginInfo) => {
const ctx = req.ctx
const rawlink = req.query.link as string
const link = decodeURIComponent(rawlink)
// Verify that link is from the same host and protocol is among the allowed
const url = new URL(link)
if (
!['http:', 'https:'].includes(url.protocol) ||
(whitelistedHostnames != null && !whitelistedHostnames.has(url.hostname))
) {
ctx.error('Rejected processing unexpected link', { link })
throw new ApiError(403, 'Cannot process provided link')
}
const options = parsePrintOptions(req.query)
const printRes = await ctx.with(
'print',
{ kind: options.kind, orientation: options.orientation },
(ctx) => print(ctx, link, options),
{
url,
viewport: options.viewport
}
)
if (printRes === undefined) {
throw new ApiError(400, 'Failed to print')
}
View on GitHub (pinned to 63e28dc964)
Solutions
- Use an https:// (or http://) URL for the link parameter.
- Ask the operator to add your link's hostname to the pod's allowedHostnames configuration, or run the pod with an empty whitelist (whitelist disabled) if appropriate.
- Verify exact hostname match — the check compares url.hostname against the Set exactly (no wildcards, no case folding).
- Make sure the link is properly encoded once, not double-encoded, so the decoded hostname is the intended one.
Example fix
// before
fetch(`/print?link=${encodeURIComponent('file:///tmp/doc.html')}`)
// after
const target = 'https://docs.example.com/report'
fetch(`/print?link=${encodeURIComponent(target)}`) // https:// and whitelisted hostname Defensive patterns
Strategy: validation
Validate before calling
function assertPrintableUrl (raw: string, allowedHostnames?: string[]): URL {
const url = new URL(decodeURIComponent(raw))
if (!['http:', 'https:'].includes(url.protocol)) {
throw new Error(`protocol not allowed: ${url.protocol}`)
}
if (allowedHostnames != null && allowedHostnames.length > 0 && !allowedHostnames.includes(url.hostname)) {
throw new Error(`hostname not whitelisted: ${url.hostname}`)
}
return url
} Type guard
function isHttpUrl (v: unknown): v is URL {
try { const u = new URL(String(v)); return u.protocol === 'http:' || u.protocol === 'https:' } catch { return false }
} Try / catch
try {
const res = await fetch(`/print?link=${encodeURIComponent(link)}`)
if (res.status === 403) {
const body = await res.json()
throw new Error(`Link rejected by print service (403): ${body.message} — check protocol and hostname whitelist`)
}
return await res.json()
} catch (err) { /* handle */ } Prevention
- Only send http(s) links; never file:, data:, or javascript: URIs.
- Confirm your target hostname is in the pod's allowedHostnames before deploying.
- Remember matching is exact — no wildcards or subdomain inference; encode the link exactly once.
- Keep an ops checklist mapping environments to whitelisted domains.
When it happens
Trigger: GET /print?link=file:///etc/passwd or link=javascript:... (bad protocol); or an http(s) link whose hostname is not in the server's allowedHostnames list; also a hostname that differs in case/subdomain from the whitelisted entry (Set lookup is exact).
Common situations: Deploying the pod with allowedHostnames configured but the app generating links with a different domain (e.g. internal k8s service name vs public domain); printing localhost links that were never whitelisted; client sending encoded URIs whose decoded hostname doesn't match.
Related errors
- BLOCKED_URL
- Token revoked
- platform.status.Forbidden
- INVALID_PROTOCOL
- Key contains invalid path sequences
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/a6427a2287ac18b1.
Report an issue: GitHub.