stablyai/orca · error · JiraApiError
Jira attachment URL must use the configured site origin.
Error message
Jira attachment URL must use the configured site origin.
What it means
Thrown by jiraRequestBinary when a fully-qualified attachment URL (or a relative path that resolves) has an origin different from the configured Jira site origin. This is a deliberate SSRF guard: Jira attachment metadata is provider-controlled, so forwarding Authorization credentials to an unexpected origin would leak them. It is a JiraApiError with status null.
Source
Thrown at src/main/jira/client.ts:505
}
if (response.status === 204) {
return null as T
}
return (await response.json()) as T
}
export async function jiraRequestBinary(
client: JiraClientForSite,
pathOrUrl: string
): Promise<{ data: ArrayBuffer; contentType: string }> {
const siteUrl = new URL(client.site.siteUrl)
const requestUrl = /^https?:\/\//i.test(pathOrUrl)
? new URL(pathOrUrl)
: new URL(`${client.site.siteUrl}${pathOrUrl}`)
if (requestUrl.origin !== siteUrl.origin) {
// Why: attachment metadata is provider-controlled; never forward Jira
// credentials if a malformed response points at another origin.
throw new JiraApiError('Jira attachment URL must use the configured site origin.', null)
}
const headers = new Headers()
// Why: attachment content is binary; forcing JSON Accept/Content-Type can
// break downloads and confuses some Atlassian edge responses.
headers.set('Accept', '*/*')
headers.set('User-Agent', JIRA_API_USER_AGENT)
headers.set('Authorization', client.authorization)
const response = await jiraFetch(requestUrl.toString(), { headers })
if (!response.ok) {
throw new JiraApiError(await readJiraError(response), response.status)
}
const contentType = response.headers.get('content-type') || 'application/octet-stream'
return {
data: await response.arrayBuffer(),
contentType
}
}
View on GitHub (pinned to 1136503c6a)
Solutions
- Reconfigure the Jira site URL so its origin matches where attachments are actually served.
- Refetch the attachment metadata to get a fresh URL and retry.
- Do NOT bypass this guard by stripping Authorization; instead download the URL unauthenticated out-of-band if the alternate origin is trusted.
- Report the malformed attachment to the Jira admin.
Example fix
// before
const { data } = await jiraRequestBinary(client, attachment.content)
// after
const attachmentUrl = new URL(attachment.content)
if (attachmentUrl.origin !== new URL(client.site.siteUrl).origin) {
await refreshAttachmentMetadata(attachment.id)
}
const { data } = await jiraRequestBinary(client, attachment.content) Defensive patterns
Strategy: validation
Validate before calling
const attachmentUrl = new URL(pathOrUrl.startsWith('http') ? pathOrUrl : client.site.siteUrl + pathOrUrl)
if (attachmentUrl.origin !== new URL(client.site.siteUrl).origin) await refreshAttachmentMetadata() Type guard
function isSameOrigin(clientUrl: string, candidate: string): boolean {
return new URL(candidate).origin === new URL(clientUrl).origin
} Try / catch
try { return await jiraRequestBinary(client, pathOrUrl) }
catch (e) {
if (e instanceof JiraApiError && /configured site origin/.test(e.message)) { await refreshAttachmentMetadata(); return downloadUnauthenticated(pathOrUrl) }
throw e
} Prevention
- Keep the Jira siteUrl aligned with the origin that serves attachments.
- Refresh cached attachment metadata after reconfiguring a site.
- Never strip Authorization to bypass the guard on untrusted origins.
When it happens
Trigger: A Jira attachment record returns a content URL on a different host (e.g. an Atlassian CDN domain not matching the site origin, a malformed/restaged attachment, or a malicious/corrupted response). Also if the user's siteUrl was changed to one origin while cached attachment URLs point at the old origin.
Common situations: Atlassian serving attachments from a different subdomain than the API site. Site URL reconfigured after attachments were cached. A proxy rewriting attachment hosts.
Related errors
- Localhost label target is not a valid URL.
- Localhost label target is not an allowed workspace port.
- auth
- token is required
- GitHub request failed ${res.status} ${res.statusText}: ${bod
AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12).
Data as JSON: /api/errors/ddcafdf8f2ef00b4.
Report an issue: GitHub.