{"record":{"id":"9bf497605451b771","repo":"FlowiseAI/Flowise","slug":"failed-to-post-url-error","errorCode":null,"errorMessage":"Failed to post ${url}: ${error}","messagePattern":"Failed to post (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/components/nodes/documentloaders/API/APILoader.ts","lineNumber":289,"sourceCode":"            throw new Error(`Failed to fetch ${url}: ${error}`)\n        }\n    }\n\n    protected async executePostRequest(url: string, headers?: ICommonObject, body?: ICommonObject, ca?: string): Promise<IDocument[]> {\n        try {\n            const config: AxiosRequestConfig = { method: 'POST', url, data: body ?? {}, headers: headers ?? {} }\n            const agentOptions = ca ? { ca } : undefined\n            const response = await secureAxiosRequest(config, 5, agentOptions)\n            const responseJsonString = JSON.stringify(response.data, null, 2)\n            const doc = new Document({\n                pageContent: responseJsonString,\n                metadata: {\n                    url\n                }\n            })\n            return [doc]\n        } catch (error) {\n            throw new Error(`Failed to post ${url}: ${error}`)\n        }\n    }\n}\n\nmodule.exports = {\n    nodeClass: API_DocumentLoaders\n}\n","sourceCodeStart":271,"sourceCodeEnd":297,"githubUrl":"https://github.com/FlowiseAI/Flowise/blob/abe4a8601a058047b350c260676826e21dd14101/packages/components/nodes/documentloaders/API/APILoader.ts#L271-L297","documentation":"Thrown by API_DocumentLoaders when an outbound POST via secureAxiosRequest rejects. Because secureAxiosRequest sets validateStatus: () => true, HTTP 4xx/5xx responses do NOT trigger this; only connection-level failures do (DNS, timeout, TLS, 'Too many redirects', or an SSRF deny-list hit from resolveAndValidate). The original error is stringified into the message, losing its shape.","triggerScenarios":"POSTing to an unreachable/typo'd URL; target server drops the connection; mutual-TLS CA mismatch (ca param wrong); request crosses more than 5 redirects; URL resolves to a private/internal IP blocked by the deny list; default 5-redirect budget exceeded.","commonSituations":"Mis-configured API node URL or headers; corporate proxy stripping the Host header; self-signed endpoint supplied without the matching 'ca' PEM; pointing at a localhost/internal service that the SSRF guard intentionally blocks.","solutions":["Verify the URL is reachable from the host (curl -X POST) and that the scheme/host are correct.","If the endpoint uses a private/self-signed CA, supply the PEM via the node's 'ca' input so secureAxiosRequest can build a pinned agent.","Check the SSRF deny list (resolveAndValidate in httpSecurity.ts) if pointing at internal infrastructure; route through a public endpoint or allow-list it.","For redirect-heavy endpoints, raise the maxRedirects budget (currently hardcoded to 5) or resolve the final URL upstream."],"exampleFix":"// before\nconst response = await secureAxiosRequest(config, 5, agentOptions)\n// after - surface the real cause instead of stringifying\ntry {\n  const response = await secureAxiosRequest(config, 5, agentOptions)\n} catch (error) {\n  if (axios.isAxiosError(error)) {\n    throw new Error(`Failed to post ${url}: ${error.code ?? 'ERR'} ${error.message}`)\n  }\n  throw new Error(`Failed to post ${url}: ${error instanceof Error ? error.message : String(error)}`)\n}","handlingStrategy":"try-catch","validationCode":"import axios from 'axios'\nimport { isWebUri } from 'valid-url'\n\nasync function preflight(url: string, body: unknown, headers: Record<string, string>, ca?: string) {\n  if (!isWebUri(url)) throw new Error(`Refusing POST: not a valid web URL: ${url}`)\n  if (body !== undefined && typeof body !== 'object') {\n    throw new Error('POST body must be an object or undefined')\n  }\n  const parsed = new URL(url)\n  if (parsed.hostname === 'localhost' || /^(10\\.|192\\.168\\.|172\\.(1[6-9]|2\\d|3[01])\\.)/.test(parsed.hostname)) {\n    // will be rejected by resolveAndValidate anyway; fail fast with a clear message\n    throw new Error('Refusing POST to private/internal host (SSRF guard would block)')\n  }\n}\n// await preflight(url, body, headers, ca) before secureAxiosRequest","typeGuard":"function isAxiosLikeError(e: unknown): e is { message: string; code?: string; response?: { status: number; data: unknown } } {\n  return typeof e === 'object' && e !== null && 'message' in e && typeof (e as any).message === 'string'\n}","tryCatchPattern":"try {\n  const docs = await apiLoader.load()\n} catch (error) {\n  const msg = error instanceof Error ? error.message : String(error)\n  if (/ENOTFOUND|ECONNREFUSED|ETIMEDOUT/.test(msg)) {\n    // transport - retry or surface to user\n  } else if (/redirect|deny|private/i.test(msg)) {\n    // SSRF guard or redirect budget - do not retry, fix the URL\n  }\n  throw error\n}","preventionTips":["Always supply the scheme (https://) in the URL input.","Provide the 'ca' PEM for self-signed endpoints; without it the TLS handshake fails inside secureAxiosRequest.","Avoid pointing at internal IPs/localhost - the SSRF deny list will reject them.","Set realistic timeouts upstream; secureAxiosRequest caps redirects at 5."],"tags":["network","http","ssrf","axios","api-loader"],"backgroundTag":null,"analyzedSha":"abe4a8601a058047b350c260676826e21dd14101","analyzedAt":"2026-08-12T16:04:40.823Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}