Shell scripts that call AWS CLI need the numeric status from the command that just ran, not from a later log message, cleanup step, or retry wrapper. Reading the status immediately after the command separates a successful result from bad syntax, missing credentials, and service-side rejection before automation branches into retry, alert, or stop behavior.
In Linux and macOS shells, $? stores the exit code from the most recent foreground command. The value changes after every command, so print or save it before running another check. PowerShell uses $LASTEXITCODE for the same kind of external-command status.
AWS CLI uses different nonzero codes for different failure boundaries. Syntax and parameter problems can stop before any service request is made, missing configuration or credentials can stop after parsing, and service errors can happen after the request reaches an AWS endpoint.
$ aws configure get region us-east-1
This local configuration command returns a simple success example without requiring credentials or contacting an AWS service.
$ echo $? 0
0 means the command completed without an AWS CLI error. For service calls, it means the CLI and the service request completed without an error response.
$ aws sts get-caller-identity --region us-east-1 aws: [ERROR]: An error occurred (NoCredentials): Unable to locate credentials. You can configure credentials by running "aws login".
Use a scratch shell, isolated config files, or a known empty profile when intentionally reproducing this failure so real credentials do not change the result.
$ echo $? 253
253 means the command syntax was valid, but the environment, configuration, or credentials prevented the command from running.
$ aws sts get-caller-identity --no-sign-request --region us-east-1 aws: [ERROR]: An error occurred (MissingAuthenticationToken) when calling the GetCallerIdentity operation: Request is missing Authentication Token
The --no-sign-request option is useful for demonstrating a service-side rejection without publishing credentials. Normal account checks should use signed credentials.
Related: How to check the current caller identity in AWS CLI
$ echo $? 254
254 means the command parsed and the request reached the service, but the service returned an error.
$ aws sts get-caller-identity --unknown-option usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters] To see help text, you can run: aws help aws <command> help aws <command> <subcommand> help aws: [ERROR]: Unknown options: --unknown-option
$ echo $? 252
252 means invalid syntax, an unknown parameter, or an invalid parameter value stopped the command before the intended service operation ran.
Code Meaning 0 Command completed without an AWS CLI or service error 1 One or more S3 transfer operations failed 2 Parse failure, or skipped files for S3 transfer commands 130 Command was interrupted with Ctrl+C 252 Invalid syntax, unknown parameter, or bad parameter value 253 Missing or invalid environment, configuration, or credentials 254 Service request was made, but the service returned an error 255 AWS CLI or service error not covered by a more specific code
2 is overloaded for S3 transfer commands, so inspect the failing command and stderr before treating it as only a parser problem.
aws sts get-caller-identity --output json status=$? if [ "$status" -ne 0 ]; then printf 'AWS CLI failed with exit code %s\n' "$status" >&2 exit "$status" fi
Any command between the aws call and status=$? overwrites the value being tested.