Dosu LogoDosu Logo
Ask
Join our Discord
Organization avatar
difyPublic
Dify
Documentsdify
Remote File Handling and Validation
Remote File Handling and Validation
Type
Topic
Status
Published
Created
Jul 29, 2026
Updated
Jul 29, 2026
Created by
Dosu Bot
Updated by
Dosu Bot

Remote File Handling and Validation#

When a workflow input file is submitted with "transfer_method": "remote_url" and a bare URL (no pre-uploaded upload_file_id), the request flows through four stages: metadata probing, filename extraction, type resolution, and config validation. The relevant source files are:

FileRole
api/factories/file_factory/remote.pyHTTP HEAD probe, filename extraction, MIME detection
api/factories/file_factory/builders.pyOrchestration, type resolution, File object construction
api/factories/file_factory/validation.pyExtension-based config validation

Entry point is _build_from_remote_url() in builders.py.

Stage 1: Remote Metadata Probing#

get_remote_file_info(url) fires an SSRF-safe HTTP HEAD request via remote_fetcher.make_request("HEAD", url, follow_redirects=True). On HTTP 200, it reads:

  • Content-Disposition → passed to extract_filename() (see next section)
  • Content-Length → stored as file_size
  • Content-Type → used as fallback MIME type if the filename extension doesn't resolve one

If no filename can be determined at all, a UUID-based fallback filename is generated using the guessed extension from the MIME type (e.g., <uuid>.jpeg). The function returns (mime_type, filename, file_size) .

Stage 2: Filename Extraction#

extract_filename(url_or_path, content_disposition) resolves a safe filename using the following priority chain:

  1. RFC 5987 filename* — Regex-extracts the filename*=<charset>'<lang>'<pct-encoded-value> form, percent-decodes via urllib.parse.unquote(value, encoding=charset, errors="replace"). This was overhauled in PR #26230 to properly handle charset/language tags and prevent path injection.

  2. Plain filename — Falls back to werkzeug's parse_options_header(), strips surrounding quotes, then percent-decodes .

  3. URL path basename — When no Content-Disposition filename is available, uses urllib.parse.urlparse(url_or_path).path to isolate the URL path (discarding query strings and hash fragments), then decodes via urllib.parse.unquote(..., errors="replace"). This was fixed in PR #35706 to correctly handle presigned S3 URLs with X-Amz-* query parameters.

Security: The final result always passes through os.path.basename() to strip any path traversal sequences. Whitespace-only or empty results return None .

Stage 3: Type Resolution#

Back in _build_from_remote_url(), the resolved filename extension and MIME type are passed to standardize_file_type(extension, mime_type) to produce a FileType enum value .

_resolve_file_type() then reconciles the detected type with the caller-supplied type field:

  • If no type is specified, the detected type wins.
  • If type == "custom", FileType.CUSTOM is returned unconditionally — extension-whitelist enforcement is deferred to the config validation stage.
  • If strict_type_validation=True and the detected type differs from the specified type, a ValueError is raised with the message "Detected file type does not match the specified type. Please verify the file." .

When is strict validation active? strict_type_validation=True is set when invoke_from == InvokeFrom.SERVICE_API, i.e., all Service API calls enforce strict type checking .

Stage 4: Config Validation#

After the File object is built, build_from_mapping() calls is_file_valid_with_config() if a FileUploadConfig is present. Validation logic:

  1. Tool files bypass config — TOOL_FILE transfer method always returns True .
  2. Type allowlist — input_file_type must be in config.allowed_file_types, or CUSTOM must be in that list .
  3. Extension whitelist (CUSTOM bucket) — When the file falls into the CUSTOM bucket (either explicitly typed as CUSTOM or when its type isn't in the allowlist), config.allowed_file_extensions is enforced. An explicitly empty list means deny all . Extension matching is case- and dot-insensitive via _normalize_extension() .
  4. Transfer method check — IMAGE files check image_config.transfer_methods; all others check allowed_file_upload_methods .

Common Error: "Detected file type does not match the specified type"#

This error requires all three conditions to hold simultaneously :

  1. Service API invocation (strict_type_validation=True)
  2. Non-null type field in the input mapping (note: "custom" is a common default)
  3. Type mismatch — the extension/MIME-derived FileType differs from the specified type

Fixes and workarounds:

  • Pass a type value that matches the file's actual extension (e.g., "document" for .txt, .pdf, .docx) .
  • Upload via /files/upload first to obtain an upload_file_id, then reference it with transfer_method: "local_file" — this avoids live URL probing entirely.
  • For presigned S3 URLs, ensure the URL path contains a file extension (e.g., ends in .jpg) because Dify's filename extraction depends on it when Content-Disposition is absent.
  • The "custom" type only avoids strict-type errors if the workflow's variable is also configured as CUSTOM; otherwise the CUSTOM extension whitelist applies.
Documents
Account Activity Tracking
Agent API Routes
Agent App Architecture
Dify Agent Server 模块分析 (Commit 55f95dbc)
Agent App Event Architecture
Agent Cost and Usage Tracking
Agent File Handling
Agent File Upload Configuration
Agent Icon Data Model
Agent Log Event Pipeline
Agent Message History
Dify Agent Server 模块分析 (Commit 55f95dbc)
Agent Model Settings
Agent Node Data Models
Agent Response Schema
Agent Runtime
Dify Agent Server 模块分析 (Commit 55f95dbc)
Agent Runtime Backend Initialization
Agent Runtime Layer Provider Registration
Dify Agent Server 模块分析 (Commit 55f95dbc)
Agent Sandbox SSRF Allowlisting
Agent Shell Layer
Agent Strategy Plugin Architecture
Agent V2 Architecture
Dify Agent Server 模块分析 (Commit 55f95dbc)
Agent V2 Configure Interface
Agent V2 Feature Flags
Agent V2 File and Vision Handling
Agent V2 Variable System
App Mode Configuration
App Publishing and Embedding
Audio to Text API
Auth Route Architecture
Automatic Rule Generation
Avatar Management
Branding Customization
Browser Tab and State Management
Builtin Tool Provider Credentials
Celery Task Resilience
Chat Avatar Rendering
Chatbot Conversation State Recovery
Chatbot Widget Embedding
Code Node Execution
Code Node Output Validation
Collaborative Workflow Editing
Conversation Auto-Naming
Credential Encryption and Secret Management
Custom Tool Authentication
Custom Tool HTTP Timeout Configuration
Custom Tool OpenAPI Integration
Data Export
Database Migration System
Database Session Management
Database Transaction Isolation
Dataset Batch Import
Dataset Deletion
Dataset Permission Model
Dataset Segmentation Configuration
Dependency Injection and Testability
Dify Agent Server 模块分析 (Commit 55f95dbc)
Dify Agent Monorepo Structure
Dify Agent Server 模块分析 (Commit 55f95dbc)
Dify Cloud Billing
Dify OpenAPI
difyctl CLI
Docker Container Security
Docker Deployment and Upgrades
Docker Frontend Configuration
Docker Image Publishing
Docker Networking
Document Indexing Operations
Edition-Based Feature Gating
Elasticsearch Integration
External Knowledge Integration
File Access Control
File Array Handling
File Download Architecture
File Download Security
File Storage Synchronization
File Upload and Download Integrity
File Upload Configuration
File Upload Processing
File URL Resolution
Flask Application Architecture
Flask Blueprint and Route Registration
Graph Streaming Infrastructure
Home Directory Management
HTTP Request Node
HTTP Request Node Key-Value Editor
HTTP Request Node Size Constraints
httpx and Gevent Compatibility
Human Input Node
Hybrid Search
Icon URL Resolution
Iframe Embedding Security
Jina Reranker Integration
JWT Authentication
Knowledge Base API
Knowledge Base Document Processing
Knowledge Base Metadata Filtering
Knowledge Base Summarization Pipeline
Langfuse Integration
Lexical Editor Integration
LLM Provider Message Validation
LLM Structured Output
Local Development Configuration
Log Filtering
Markdown Rendering
MCP Client Transport and Connectivity
MCP Protocol Integration for Dify Workflows
MCP OAuth Integration
MCP Protocol Integration
Dify Agent Server 模块分析 (Commit 55f95dbc)
MCP Protocol Integration for Dify Workflows
MCP Provider Architecture
MCP Tool Integration
MCP Protocol Integration for Dify Workflows
MCP Tool Parameter Binding
Messaging Platform Integration
Milvus Integration
Model Provider Error Handling
Monaco Editor Integration
Multi-Tenant Context Propagation
Multimodal Knowledge Base Support
Next.js Routing and Redirects
Next.js SSR Authentication
Nginx Reverse Proxy Configuration
OAuth Login Flow
Observability and Tracing
OpenAI-Compatible Server Integration
OpenDAL Storage Backend
Ops Trace Data Models
Parallel Workflow Execution
Parent-Child Retrieval Architecture
Plugin API Key Configuration
Plugin Architecture
Plugin Credential Management
Plugin Daemon Architecture
Plugin Daemon Communication
Plugin Daemon Model Parameter Handling
Plugin Daemon Port Configuration
Plugin Database Integrity
Plugin Error Handling
Plugin Lifecycle Management
Plugin Model Caching
Plugin Permissions
Plugin Storage Configuration
Plugin System Timeouts
Plugin Taxonomy and Validation
Plugin Trigger OAuth Refresh
PNPM Monorepo Dependency Management
PostgreSQL Generated Columns
Provider Model & Credential Management
Pyrefly Type Checker
Rate Limiting and Concurrency Control
RBAC Initialization
Reasoning Tag Filtering
Redis Connection Management
Redis Streaming Resilience
Release Breaking Changes
Remote File Handling and Validation
Retrieval Filtering and Scoring
RTL Locale Support
Sandbox Code Execution
Sandbox Network Isolation
Sandbox Seccomp Security
Segment Update and Attachment Lifecycle
Server Deployment Configuration
Service API Pagination
Shell Provider Lifecycle
Snippet Variable Handling
SQLite Test Infrastructure
SSE Stream Lifecycle
SSE Stream Terminal Event Delivery
SSL/TLS Certificate Management
SSR Data Fetching
SSRF Proxy
Suggested Questions After Answer
Summary Index
Tenant-Isolated Document Indexing Queue
Test Doubles and In-Memory Repositories
Dify Agent Server 模块分析 (Commit 55f95dbc)
TiDB Vector Full-Text Search
Timestamp Management
Tool File URL Signing
Tool Node Input Validation
Tool Provider Authorization
Trace Task Pipeline
TTS Audio Playback
User and Tenant Context Propagation
User Roles and Permissions
Variable Pool Falsy Value Handling
Variable Resolution and Template Substitution
Vector Database Plugin Architecture
Vector Store Integration
Vite Configuration
Weaviate Vector Store
Web Container Docker Configuration
Webhook Trigger System
WebSocket Service Architecture
Word Document Extraction
Workflow Agent Node Configuration
Workflow Agent Retry Configuration
Workflow and Agent Composition
Workflow Conditional Branching
Workflow Container Nodes
Workflow Conversation State Management
Workflow Draft Synchronization
Workflow Execution Dispatch
Workflow Execution Persistence
Workflow Fail Branch Architecture
Workflow File Handling
Workflow Iteration Node Execution
Workflow LLM Node Configuration
Workflow Memory Management
Dify Agent Server 模块分析 (Commit 55f95dbc)
Workflow Node Canvas Summary Rendering
Workflow Node Versioning
Workflow Pause-Resume State Management
Workflow Resume Architecture
Workflow Run State Management
Workflow Schedule Triggers
Workflow Test Run Execution
Workflow Timeout and Execution Limits
Workflow Variable Size Management