# Fix AWS Parameter Store Error

Your application can't retrieve parameters from AWS Systems Manager Parameter Store. You're getting errors like "AccessDeniedException," "ParameterNotFound," or "ThrottlingException." Parameter Store is a simple but critical service for storing configuration data, secrets, and application settings, and when it fails, your application might not start or misconfigure itself.

This guide covers the common Parameter Store errors and how to fix them.

Diagnosis Commands

First, verify your identity:

bash
aws sts get-caller-identity

List parameters you have access to:

bash
aws ssm describe-parameters \
  --query 'Parameters[*].[Name,Type,Description,LastModifiedDate]'

Try to get a specific parameter:

bash
aws ssm get-parameter \
  --name /my-app/database-url \
  --query 'Parameter.[Name,Value,Type]'

For SecureString parameters (encrypted):

bash
aws ssm get-parameter \
  --name /my-app/database-password \
  --with-decryption \
  --query 'Parameter.Value'

Check parameter metadata:

bash
aws ssm describe-parameters \
  --filters "Name=Name,Values=/my-app/database-url" \
  --query 'Parameters[*].[Name,Type,KeyId,Tier]'

Check your IAM policies:

bash
aws iam list-user-policies --user-name my-user
aws iam list-attached-user-policies --user-name my-user

Get policy details:

bash
aws iam get-user-policy \
  --user-name my-user \
  --policy-name SSMParameterPolicy

Use policy simulator:

bash
aws iam simulate-principal-policy \
  --policy-source-arn arn:aws:iam::123456789012:user/my-user \
  --action-names ssm:GetParameter,ssm:GetParameters \
  --resource-arns arn:aws:ssm:us-east-1:123456789012:parameter/my-app/*

Check for throttling:

bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/SSM \
  --metric-name ThrottledRequests \
  --dimensions Name=Operation,Value=GetParameter \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 60 \
  --statistics Sum

Common Causes and Solutions

Parameter Not Found

The parameter doesn't exist or the name is wrong:

bash
aws ssm describe-parameters \
  --filters "Name=Name,Values=/my-app/database-url"

If empty, the parameter doesn't exist. Create it:

bash
aws ssm put-parameter \
  --name /my-app/database-url \
  --value "jdbc:postgresql://mydb.example.com:5432/app" \
  --type String \
  --description "Database connection URL" \
  --tier Standard

Common naming mistakes: - Missing leading / (all names should start with / for hierarchical paths) - Wrong case (Parameter Store is case-sensitive) - Wrong path component

```bash # Bad: No leading slash aws ssm get-parameter --name my-app/database-url

# Good: With leading slash aws ssm get-parameter --name /my-app/database-url ```

List all parameters to find the correct name:

bash
aws ssm describe-parameters \
  --query 'Parameters[*].Name' \
  --output text | tr '\t' '\n' | grep my-app

Access Denied

Missing IAM permissions to read parameters:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:GetParameter",
        "ssm:GetParameters",
        "ssm:GetParametersByPath",
        "ssm:DescribeParameters"
      ],
      "Resource": "arn:aws:ssm:us-east-1:123456789012:parameter/my-app/*"
    }
  ]
}

Apply the policy:

bash
aws iam put-role-policy \
  --role-name my-role \
  --policy-name SSMParameterAccess \
  --policy-document file://ssm-policy.json

For specific parameters:

json
{
  "Resource": [
    "arn:aws:ssm:us-east-1:123456789012:parameter/my-app/database-url",
    "arn:aws:ssm:us-east-1:123456789012:parameter/my-app/api-key"
  ]
}

SecureString Without KMS Permission

SecureString parameters use KMS for encryption:

bash
aws ssm describe-parameters \
  --filters "Name=Type,Values=SecureString" \
  --query 'Parameters[*].[Name,KeyId]'

If KeyId shows a specific key (not aws/ssm), you need KMS decrypt permission:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ssm:GetParameter",
        "kms:Decrypt"
      ],
      "Resource": [
        "arn:aws:ssm:us-east-1:123456789012:parameter/my-app/secure-*",
        "arn:aws:kms:us-east-1:123456789012:key/my-key-id"
      ]
    }
  ]
}

For default encryption (alias/aws/ssm):

json
{
  "Resource": "arn:aws:kms:us-east-1:123456789012:alias/aws/ssm"
}

Permission Boundary Restriction

Permission boundaries limit maximum permissions:

bash
aws iam get-role \
  --role-name my-role \
  --query 'Role.PermissionsBoundary'

If set, the boundary must allow SSM actions:

bash
aws iam get-policy-version \
  --policy-arn arn:aws:iam::123456789012:policy/my-boundary \
  --version-id v1 \
  --query 'Document' \
  --output text | jq '.Statement[] | select(.Action | contains("ssm"))'

Parameter Version Issues

Parameters have versions. If you're accessing a deleted version:

bash
aws ssm get-parameter \
  --name /my-app/database-url \
  --query 'Parameter.Version'

Get parameter history:

bash
aws ssm get-parameter-history \
  --name /my-app/database-url \
  --query 'Parameters[*].[Version,LastModifiedDate,Value]'

Specify a version if needed:

bash
aws ssm get-parameter \
  --name /my-app/database-url \
  --version 2

Throttling Errors

Parameter Store has API rate limits. Standard tier: 40 transactions per second per region per account. Advanced tier: higher limits.

Check throttling metrics:

bash
aws cloudwatch get-metric-statistics \
  --namespace AWS/SSM \
  --metric-name ThrottledRequests \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%SZ) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \
  --period 60 \
  --statistics Sum
  1. 1.Reduce API calls by:
  2. 2.Using GetParameters for multiple parameters in one call:
bash
aws ssm get-parameters \
  --names "/my-app/database-url" "/my-app/api-key" "/my-app/config" \
  --query 'Parameters[*].[Name,Value]'
  1. 1.Using GetParametersByPath for hierarchical retrieval:
bash
aws ssm get-parameters-by-path \
  --path /my-app/ \
  --recursive \
  --with-decryption \
  --query 'Parameters[*].[Name,Value]'
  1. 1.Upgrade to Advanced tier for higher limits:
bash
aws ssm put-parameter \
  --name /my-app/config \
  --value "config-value" \
  --type String \
  --tier Advanced \
  --overwrite
  1. 1.Implement caching in your application:

```python import boto3 from functools import lru_cache

ssm = boto3.client('ssm')

@lru_cache(maxsize=128) def get_cached_parameter(name, ttl=300): return ssm.get_parameter(Name=name, WithDecryption=True)['Parameter']['Value'] ```

Cross-Account Access

To access parameters in another account:

In Account B (parameter owner):

  1. 1.No direct sharing. Options:
  2. 2.Share via AWS Resource Access Manager (RAM) - not available for Parameter Store
  3. 3.Replicate parameters to Account A
  4. 4.Use Lambda in Account B to expose parameters

Alternative: Use Systems Manager Shared Parameters:

```bash # In Account B aws ssm put-parameter \ --name /shared/database-url \ --value "value" \ --type String

# Can't directly share, need alternative approaches ```

Workaround using Lambda:

```python # Lambda in Account B import boto3

def lambda_handler(event, context): ssm = boto3.client('ssm') return ssm.get_parameter(Name=event['parameter_name'], WithDecryption=True) ```

Invalid Parameter Value

Parameter value has format issues:

bash
aws ssm put-parameter \
  --name /my-app/invalid \
  --value "value with special characters" \
  --type StringList

StringList values must be comma-separated without spaces:

```bash # Bad: Spaces around commas aws ssm put-parameter --name /my-app/list --value "a, b, c" --type StringList

# Good: No spaces aws ssm put-parameter --name /my-app/list --value "a,b,c" --type StringList ```

Parameter Deleted

Parameter was deleted but code still references it:

bash
aws ssm describe-parameters \
  --filters "Name=Name,Values=/my-app/deleted-param"

If empty, recreate the parameter:

bash
aws ssm put-parameter \
  --name /my-app/deleted-param \
  --value "new value" \
  --type String

Label Issues

Parameters can have labels pointing to specific versions:

bash
aws ssm get-parameter \
  --name /my-app/config:latest \
  --query 'Parameter.[Value,Version]'

Check labels:

bash
aws ssm list-tags-for-resource \
  --resource-type Parameter \
  --resource-id /my-app/config

Wrong Region

Parameters are region-specific. Ensure you're using the correct region:

bash
aws ssm describe-parameters \
  --region us-east-1 \
  --query 'Parameters[*].Name'

Set region in your SDK:

```python import boto3

ssm = boto3.client('ssm', region_name='us-east-1') ```

Verification Steps

After fixing, verify parameter access:

bash
aws ssm get-parameter \
  --name /my-app/database-url \
  --with-decryption \
  --query 'Parameter.[Name,Type,Value]'

Get all parameters under a path:

bash
aws ssm get-parameters-by-path \
  --path /my-app/ \
  --recursive \
  --with-decryption \
  --query 'Parameters[*].[Name,Value]'

Test multiple parameters:

bash
aws ssm get-parameters \
  --names "/my-app/database-url" "/my-app/api-key" \
  --with-decryption \
  --query '[Parameters[*].Name,InvalidParameters]'

Create diagnostic script:

```bash #!/bin/bash PARAM_NAME="/my-app/database-url"

echo "Parameter Store Diagnostics" echo "==========================="

echo "1. Caller Identity:" aws sts get-caller-identity

echo "" echo "2. Parameter Exists:" aws ssm describe-parameters \ --filters "Name=Name,Values=$PARAM_NAME" \ --query 'Parameters[*].[Name,Type,Tier,KeyId,LastModifiedDate]'

echo "" echo "3. Parameter Value:" aws ssm get-parameter \ --name $PARAM_NAME \ --with-decryption \ --query 'Parameter.[Name,Value,Version,Type]' 2>&1

echo "" echo "4. IAM Policies for SSM:" aws iam list-role-policies \ --role-name $(aws sts get-caller-identity --query Arn --output text | cut -d'/' -f2) \ --query 'PolicyNames' 2>&1 || echo "Using user policies" aws iam list-user-policies \ --user-name $(aws sts get-caller-identity --query Arn --output text | cut -d'/' -f2) \ --query 'PolicyNames' 2>&1

echo "" echo "5. Policy Simulator Test:" aws iam simulate-principal-policy \ --policy-source-arn $(aws sts get-caller-identity --query Arn --output text) \ --action-names ssm:GetParameter \ --resource-arns arn:aws:ssm:*:*:parameter$PARAM_NAME \ --query 'EvaluationResults[*].[EvalActionName,EvalResourceName,EvalDecision]'

echo "" echo "6. Recent Throttling:" aws cloudwatch get-metric-statistics \ --namespace AWS/SSM \ --metric-name ThrottledRequests \ --start-time $(date -u -d '30 minutes ago' +%Y-%m-%dT%H:%M:%SZ) \ --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \ --period 60 \ --statistics Sum ```

Set up monitoring:

bash
aws cloudwatch put-metric-alarm \
  --alarm-name ssm-parameter-throttled \
  --alarm-description "Parameter Store API throttled" \
  --namespace AWS/SSM \
  --metric-name ThrottledRequests \
  --statistic Sum \
  --period 60 \
  --threshold 10 \
  --comparison-operator GreaterThanThreshold \
  --evaluation-periods 1 \
  --alarm-actions arn:aws:sns:us-east-1:123456789012:alerts