{"record":{"id":"3df18c105aa04b55","repo":"laurent22/joplin","slug":"aws-s3-bucket-not-found-synctargetamazons3-s3bu","errorCode":null,"errorMessage":"AWS S3 bucket not found: ${SyncTargetAmazonS3.s3BucketName()}","messagePattern":"AWS S3 bucket not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/lib/SyncTargetAmazonS3.js","lineNumber":127,"sourceCode":"\t\t\terrorMessage: '',\n\t\t};\n\t\ttry {\n\t\t\tconst fileApi = await SyncTargetAmazonS3.newFileApi_(SyncTargetAmazonS3.id(), options);\n\t\t\tfileApi.requestRepeatCount_ = 0;\n\n\t\t\tconst headBucketReq = new Promise((resolve, reject) => {\n\t\t\t\tfileApi.driver().api().send(\n\n\t\t\t\t\tnew HeadBucketCommand({\n\t\t\t\t\t\tBucket: options.path(),\n\t\t\t\t\t}), (error, response) => {\n\t\t\t\t\t\tif (error) reject(error);\n\t\t\t\t\t\telse resolve(response);\n\t\t\t\t\t});\n\t\t\t});\n\t\t\tconst result = await headBucketReq;\n\n\t\t\tif (!result) throw new Error(`AWS S3 bucket not found: ${SyncTargetAmazonS3.s3BucketName()}`);\n\t\t\toutput.ok = true;\n\t\t} catch (error) {\n\t\t\tif (error.message) {\n\t\t\t\toutput.errorMessage = error.message;\n\t\t\t}\n\t\t\tif (error.code) {\n\t\t\t\toutput.errorMessage += ` (Code ${error.code})`;\n\t\t\t}\n\t\t}\n\n\t\treturn output;\n\t}\n\n\tasync initFileApi() {\n\t\tconst appDir = '';\n\t\tconst fileApi = new FileApi(appDir, new FileApiDriverAmazonS3(this.api(), SyncTargetAmazonS3.s3BucketName()));\n\t\tfileApi.setSyncTargetId(SyncTargetAmazonS3.id());\n","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/laurent22/joplin/blob/2654b33620775080d1d59c552259d41e33dad3d2/packages/lib/SyncTargetAmazonS3.js#L109-L145","documentation":"Thrown by SyncTargetAmazonS3.checkConfig after a HeadBucketCommand against the configured bucket. If the AWS SDK resolves the promise but with a falsy result, the bucket is treated as not found / not accessible. The bucket name comes from SyncTargetAmazonS3.s3BucketName(). Other AWS errors propagate via the catch block and surface as errorMessage instead.","triggerScenarios":"checkConfig() runs HeadBucketCommand({ Bucket: options.path() }) — the promise resolves to a falsy value (no error thrown, but no bucket metadata either). Typically indicates the bucket name is wrong, the region is wrong, or credentials lack s3:ListBucket on that bucket.","commonSituations":"Typo in the S3 sync path; bucket exists in a different region; IAM credentials have no HeadBucket permission; bucket name with a trailing slash; using a virtual-host vs path-style URL mismatch.","solutions":["Verify the bucket name exactly (no s3:// prefix, no trailing slash) in Joplin's sync settings.","Confirm the bucket's region matches what Joplin is configured to use.","Ensure the IAM user has s3:ListBucket and s3:GetObject/s3:PutObject on the bucket ARN.","Test with `aws s3 ls s3://<bucket>` using the same credentials to isolate Joplin vs AWS."],"exampleFix":"# before\naws s3 ls s3://my-buket   # NoSuchBucket\n# after (fix typo in Joplin sync settings)\nbucket: my-bucket\naws s3 ls s3://my-bucket   # OK","handlingStrategy":"validation","validationCode":"// Pre-check bucket accessibility with the same AWS creds before starting sync.\nconst { HeadBucketCommand } = require('@aws-sdk/client-s3');\nconst ok = await s3Client.send(new HeadBucketCommand({ Bucket: bucketName }));\nif (!ok) throw new Error(`Bucket not reachable: ${bucketName}`);","typeGuard":"const isNonEmptyBucketName = (s) => typeof s === 'string' && s.length > 0 && !s.includes('://') && !s.endsWith('/');","tryCatchPattern":"try { await SyncTargetAmazonS3.checkConfig(options); }\ncatch (e) { if (/S3 bucket not found/.test(e.message)) { /* verify name/region/IAM */ } else throw e; }","preventionTips":["Verify the bucket name with `aws s3 ls` using the same credentials before configuring Joplin.","Confirm the IAM policy grants s3:HeadBucket, s3:ListBucket, s3:GetObject, s3:PutObject on the bucket ARN."],"tags":["sync","aws","s3","network","configuration"],"backgroundTag":null,"analyzedSha":"2654b33620775080d1d59c552259d41e33dad3d2","analyzedAt":"2026-08-12T14:26:46.263Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}