ATH-MaaS/Pixelle-Video · error · Exception
Failed to upload file: {response.text}
Error message
Failed to upload file: {response.text} What it means
upload_file_to_oss posts the file to the OSS upload_host from the policy and raises Exception on a non-200 status, including the OSS response body. The credentials were obtained, but the actual binary upload to the OSS bucket was rejected.
Source
Thrown at pixelle_video/services/api_services/image_processor.py:335
with open(file_path, 'rb') as file:
files = {
'OSSAccessKeyId': (None, policy_data['oss_access_key_id']),
'Signature': (None, policy_data['signature']),
'policy': (None, policy_data['policy']),
'x-oss-object-acl': (None, policy_data['x_oss_object_acl']),
'x-oss-forbid-overwrite': (None, policy_data['x_oss_forbid_overwrite']),
'key': (None, key),
'success_action_status': (None, '200'),
'file': (safe_file_name, file)
}
response = requests.post(
policy_data['upload_host'],
files=files,
proxies=self._proxies(),
)
if response.status_code != 200:
raise Exception(f"Failed to upload file: {response.text}")
# Construct OSS URL correctly: oss://<bucket>/<key>
# Extract bucket from upload_host (e.g., https://dashscope-instant.oss-cn-beijing.aliyuncs.com)
upload_host = policy_data['upload_host']
bucket_name = ""
if '://' in upload_host:
domain = upload_host.split('://')[1]
bucket_name = domain.split('.')[0]
if bucket_name:
return f"oss://{bucket_name}/{key}"
else:
# Fallback if parsing fails (though unlikely for standard OSS hosts)
# If the original code's assumption that key was self-sufficient was somehow valid, logic is here.
# But normally, oss://<key> is wrong if key doesn't have bucket.
return f"oss://{key}"
def upload(self, file_path: str) -> str:View on GitHub (pinned to 848b054e4f)
Solutions
- Check response.text in the error — OSS returns XML explaining the rejection (SignatureDoesNotMatch, AccessDenied, Expired).
- Fetch a fresh upload policy immediately before each upload; do not reuse stale policy_data.
- Ensure multipart fields exactly match the policy (policy, signature, OSSAccessKeyId, key, success_status) with the file last.
- Verify network/proxy settings allow reaching the OSS host (self._proxies() configuration).
Example fix
// before policy = processor.get_upload_policy() # ... long processing ... url = processor.upload_file_to_oss(policy, path) # policy expired // after policy = processor.get_upload_policy() # fetch fresh, upload immediately url = processor.upload_file_to_oss(policy, path)
Defensive patterns
Strategy: retry
Validate before calling
import os, time
assert os.path.exists(file_path), "file missing before OSS upload"
assert policy_data and policy_data.get("upload_host"), "no upload policy — fetch one first" Type guard
def is_fresh_policy(policy, max_age_s=600) -> bool:
return policy is not None and (time.time() - policy.get("fetched_at", 0)) < max_age_s Try / catch
try:
url = processor.upload_file_to_oss(policy_data, file_path)
except Exception as e:
logging.error(f"OSS upload failed: {e}")
fresh = processor.get_upload_policy() # policy may have expired
url = processor.upload_file_to_oss(fresh, file_path) Prevention
- Fetch a fresh policy immediately before each upload; never reuse stale ones
- Match multipart form fields exactly (file field last)
- Check the OSS XML body in the error for SignatureDoesNotMatch/Expired codes
- Verify proxy settings allow direct access to the OSS host
When it happens
Trigger: POST to policy_data['upload_host'] returns non-200: expired upload policy/credentials (they are temporary), missing or wrong form fields (key, policy, signature, OSSAccessKeyId, file), file too large, or OSS endpoint unreachable.
Common situations: Reusing a cached policy_data after it expired, constructing the multipart form incorrectly (file must be the last field), proxy interference breaking the OSS upload, uploading before fetching a fresh policy.
Related errors
AI-assisted analysis of ATH-MaaS/Pixelle-Video@848b054e4f (2026-08-30).
Data as JSON: /api/errors/90deef19fbcdb618.
Report an issue: GitHub.