laurent22/joplin · error · JoplinError

rejectedByTarget

rejectedByTarget

Error message

Do not have proper permissions to Bucket

What it means

A JoplinError (code 'rejectedByTarget') thrown in the S3 driver's read/get path when the server returns an AccessDenied error parsed from the XML response body. It signals the configured AWS credentials lack read (GetObject/list) permission on the target bucket. Upstream sync code treats 'rejectedByTarget' specially — the item is skipped and logged rather than marked 'cannotSyncItem'.

Source

Thrown at packages/lib/file-api-driver-amazon-s3.js:281

			// This means that the error was on the Desktop client side and we need to handle that.
			// On Mobile it won't match because FetchError is a node-fetch feature.
			// https://github.com/node-fetch/node-fetch/blob/main/docs/ERROR-HANDLING.md
			if (error.name === 'FetchError') { throw error.message; }

			let parsedOutput = '';

			// If error.output is not xml the last else case should
			// actually let us see the output of error.
			if (error.output) {
				parsedOutput = parser.parse(error.output);
				if (this.hasErrorCode_(parsedOutput.Error, 'AuthorizationHeaderMalformed')) {
					throw error.output;
				}

				if (this.hasErrorCode_(parsedOutput.Error, 'NoSuchKey')) {
					return null;
				} else if (this.hasErrorCode_(parsedOutput.Error, 'AccessDenied')) {
					throw new JoplinError('Do not have proper permissions to Bucket', 'rejectedByTarget');
				}
			} else {
				if (error.output) {
					throw error.output;
				} else {
					throw error;
				}
			}
		}
	}

	// Don't need to make directories, S3 is key based storage.
	async mkdir() {
		return true;
	}

	async put(path, content, options = null) {
		const remotePath = this.makePath_(path);

View on GitHub (pinned to 2654b33620)

Solutions

  1. Update the IAM policy for the configured credentials to grant s3:GetObject (and s3:ListBucket if listing fails) on the bucket.
  2. If using SSE-KMS, ensure kms:Decrypt permission on the encrypting key.
  3. Verify the bucket policy explicitly allows the principal and doesn't have an explicit Deny.
  4. Confirm the bucket name and region in the sync config are correct.
Defensive patterns

Strategy: try-catch

Validate before calling

// Before configuring S3 sync, validate credentials have read access
// (best done via a preflight HEAD/GetObject on a known key)
try {
  await s3.send(new HeadObjectCommand({ Bucket, Key: '.joplin' }));
} catch (e) {
  // credentials lack read permission; fix IAM before syncing
}

Type guard

import JoplinError from './JoplinError';
function isRejectedByTarget(e: unknown): e is JoplinError {
  return e instanceof JoplinError && (e as any).code === 'rejectedByTarget';
}

Try / catch

try {
  await driver.get(path);
} catch (error) {
  if (isRejectedByTarget(error)) {
    // skip this item; log a warning; do not mark as cannotSyncItem
    logger.warn('Item rejected by target', path, error.message);
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: The S3 driver performs a GET-like operation (read of an object); AWS returns an XML error containing <Code>AccessDenied</Code>; the driver parses it and throws this. The AWS credentials in the sync config have permission to reach the bucket but not to read objects.

Common situations: IAM user/role with write but not read permissions on the bucket; bucket policy denies the principal; KMS key missing decrypt permission for SSE-encrypted objects; wrong bucket region/endpoint causing auth mismatch; credentials rotated to a lesser role.

Related errors


AI-assisted analysis of laurent22/joplin@2654b33620 (2026-08-12). Data as JSON: /api/errors/bd559187cb114880. Report an issue: GitHub.