AWS Organizations SCP Quotas Have Doubled, So I Actually Tried Attaching 10 Policies and a 10,240-Character Policy

AWS Organizations SCP Quotas Have Doubled, So I Actually Tried Attaching 10 Policies and a 10,240-Character Policy

AWS Organizations raised its SCP quotas in May 2026: attachments from 5 to 10, policy size from 5,120 to 10,240 characters. I tested behavior at the new limits, the errors when exceeded, and CLI whitespace handling.
2026.05.16

This page has been translated by machine translation. View original

On May 15, 2026, an increase to the AWS Organizations SCP quotas was announced.

https://aws.amazon.com/jp/about-aws/whats-new/2026/05/aws-organizations-increased-scp-quotas/

https://dev.classmethod.jp/articles/aws-organizations-scp-quota-10-per-entity/

These are the main changes in this update.

Item Old New
Number of SCP attachments per target (root/OU/account) 5 10
SCP policy size 5,120 characters 10,240 characters

https://docs.aws.amazon.com/organizations/latest/userguide/orgs_reference_limits.html

The number of attachments and the policy size have each doubled. Because AWS Organizations is a global service, this quota change becomes available without any action on the user's side. No configuration changes are needed in individual Regions.

If you left FullAWSAccess as the default, under the old limit you could add only 4 more custom SCPs. With the new limit of 10, you can now manage policies separated by purpose, as shown below.

SCP Description
FullAWSAccess The SCP attached by default. Assumes a Deny-list approach
Region restriction Deny everything outside the allowed Regions
IP restriction Deny operations from outside the corporate network
Guardrail (IAM) Prevent deletion/modification of IAM roles
Guardrail (CloudTrail) Prevent disabling CloudTrail
Guardrail (S3) Prevent S3 public access
Guardrail (EC2) Restrict specific instance types
Guardrail (Organizations) Prevent leaving the Organization
Cost control Restrict use of expensive services

Under the old limit, compromises such as "combining the Region restriction and guardrails into a single SCP" were necessary, but with the new limit you can manage one SCP per purpose with one responsibility each, and the impact scope of changes also becomes clear.

Test 1: Attachment Limit

I created an empty OU for testing and attached dummy SCPs one after another in addition to FullAWSAccess (attached automatically). Since I only wanted to test the number of attachments, I used dummy SCPs with Allow * that add no permission restrictions.

Test Description Result
Exceeding the old limit FullAWSAccess + 6 = 7 total ✅ Success
Reaching the new limit FullAWSAccess + 9 = 10 total ✅ Success
Exceeding the new limit Attempt to attach an 11th ❌ Error

This is the list-policies-for-target output with 10 attachments successfully made.

aws organizations list-policies-for-target \
  --target-id ou-xxxx-xxxxxxxx \
  --filter SERVICE_CONTROL_POLICY \
  --region us-east-1
{
    "Policies": [
        {"Id": "p-FullAWSAccess", "Name": "FullAWSAccess"},
        {"Id": "p-abc00001", "Name": "SCP-QuotaTest-01"},
        {"Id": "p-abc00002", "Name": "SCP-QuotaTest-02"},
        {"Id": "p-abc00003", "Name": "SCP-QuotaTest-03"},
        {"Id": "p-abc00004", "Name": "SCP-QuotaTest-04"},
        {"Id": "p-abc00005", "Name": "SCP-QuotaTest-05"},
        {"Id": "p-abc00006", "Name": "SCP-QuotaTest-06"},
        {"Id": "p-abc00007", "Name": "SCP-QuotaTest-07"},
        {"Id": "p-abc00008", "Name": "SCP-QuotaTest-08"},
        {"Id": "p-abc00009", "Name": "SCP-QuotaTest-09"}
    ]
}

When I tried to attach an 11th, the following error was returned.

An error occurred (ConstraintViolationException) when calling the AttachPolicy operation:
You have attached the maximum number of policies to the specified target.

Additional error details:
Reason: MAX_POLICY_TYPE_ATTACHMENT_LIMIT_EXCEEDED

Policies applied through inheritance are not counted toward the attachment count. Policies attached to a parent OU are evaluated through inheritance, but they do not consume the attachment quota of child OUs (only direct attachments are counted).

When isolating causes during IaC execution, it is more reliable to decide based on the Reason code than on the human-readable message body. An attachment count overrun is MAX_POLICY_TYPE_ATTACHMENT_LIMIT_EXCEEDED, and a size overrun, described below, is POLICY_CONTENT_LIMIT_EXCEEDED.

Test 2: Policy Size Limit

Assuming a use case where an IP restriction SCP lists many site CIDRs, I adjusted the character count by lining up a large number of CIDRs in Condition.NotIpAddress.aws:SourceIp.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "DenyUnlessFromApprovedIPs",
    "Effect": "Deny",
    "Action": "*",
    "Resource": "*",
    "Condition": {
      "NotIpAddress": {
        "aws:SourceIp": [
          "10.0.0.0/24",
          "10.0.1.0/24",
          "10.0.2.0/24",
          ...(中略、全体で 650 CIDRs)...
          "10.2.137.0/24"
        ]
      }
    }
  }]
}

In this test data, up to about 650 CIDRs fit under the new limit. The number that actually fits varies depending on the length of the CIDR strings and the policy structure.

I measured the byte count of the compact JSON, composed only of ASCII, with wc -c (since it is ASCII only, it matches the character count. The official documentation uses the term "characters").

Test Policy size Result
Within the limit 10,236 characters (650 CIDRs) ✅ Success
Over the limit 10,252 characters (651 CIDRs) ❌ Error

This is the error when the limit is exceeded.

An error occurred (ConstraintViolationException) when calling the CreatePolicy operation:
You have exceeded the maximum policy size.

Additional error details:
Reason: POLICY_CONTENT_LIMIT_EXCEEDED

Test 3: Handling of Whitespace

The official documentation states that whitespace is automatically removed in the console, and is stored as is with the CLI/SDK. This time I confirmed that whitespace is included in the size when saving with the CLI.

In the Management Console, extra whitespace between JSON elements is automatically removed on save, so it is not included in the size. On the other hand, with the CLI/SDK the policy body you send is handled as is, so line breaks and indentation are also included in the size.

Save method Policy size (when sent via CLI) Result
CLI pretty-print 17,359 characters (*9,448 characters in compact terms, within the limit) ❌ The 17,359 characters at send time were counted as is, exceeding the limit
CLI pretty-print 5,950 characters (3,239 characters in compact terms) ✅ Success, confirmed that whitespace is retained

Even a policy that would fit within the limit if converted to compact failed with a size-exceeded error when saved via the CLI in pretty-printed form. I also confirmed that when retrieved with describe-policy, the indentation and line breaks were retained as is. When managing SCPs with the CLI, we recommend saving them as compact JSON (using jq -c or similar).

Reproduction Steps

The following script can reproduce the tests of the attachment limit and the policy size limit. You need credentials for the Organizations management account and an Organization with SCPs enabled. Create an empty OU for testing and run it there. Do not run it in an OU to which production accounts belong.

The script generates policies near the limit that fit within 10,240 characters. The character counts in the text are values measured during testing.

test-scp-quota.sh (click to expand)
#!/bin/bash
# AWS Organizations SCP クォータ引き上げ検証スクリプト
# 前提: Organizations 管理アカウントの認証情報、python3
# 実行: ./test-scp-quota.sh

set -euo pipefail
REGION="us-east-1"
SCP_CONTENT='{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}'

GREEN='\033[0;32m'; RED='\033[0;31m'; NC='\033[0m'
pass() { echo -e "${GREEN}✅ PASS${NC}: $1"; }
fail() { echo -e "${RED}❌ FAIL${NC}: $1"; }

ROOT_ID=$(aws organizations list-roots --region "$REGION" --query 'Roots[0].Id' --output text)

echo "=== Part 1: アタッチ数上限テスト ==="
OU_ID=$(aws organizations create-organizational-unit \
  --parent-id "$ROOT_ID" --name "SCP-Quota-Test" \
  --region "$REGION" --query 'OrganizationalUnit.Id' --output text)

POLICY_IDS=()
for i in $(seq -w 1 10); do
  PID=$(aws organizations create-policy \
    --name "SCP-QuotaTest-${i}" --description "Quota test ${i}" \
    --type SERVICE_CONTROL_POLICY --content "$SCP_CONTENT" \
    --region "$REGION" --query 'Policy.PolicySummary.Id' --output text)
  POLICY_IDS+=("$PID")
  sleep 1
done

for i in $(seq 0 5); do
  aws organizations attach-policy --policy-id "${POLICY_IDS[$i]}" --target-id "$OU_ID" --region "$REGION"
  sleep 1
done
COUNT=$(aws organizations list-policies-for-target --target-id "$OU_ID" \
  --filter SERVICE_CONTROL_POLICY --region "$REGION" --query 'length(Policies)' --output text)
[ "$COUNT" -eq 7 ] && pass "旧上限超え: ${COUNT}個" || fail "期待7個、実際${COUNT}個"

for i in $(seq 6 8); do
  aws organizations attach-policy --policy-id "${POLICY_IDS[$i]}" --target-id "$OU_ID" --region "$REGION"
  sleep 1
done
COUNT=$(aws organizations list-policies-for-target --target-id "$OU_ID" \
  --filter SERVICE_CONTROL_POLICY --region "$REGION" --query 'length(Policies)' --output text)
[ "$COUNT" -eq 10 ] && pass "新上限到達: ${COUNT}個" || fail "期待10個、実際${COUNT}個"

if ERROR=$(aws organizations attach-policy --policy-id "${POLICY_IDS[9]}" \
  --target-id "$OU_ID" --region "$REGION" 2>&1); then
  fail "11個目がエラーにならなかった"
else
  echo "$ERROR" | grep -q "MAX_POLICY_TYPE_ATTACHMENT_LIMIT_EXCEEDED" && \
    pass "11個目でエラー: MAX_POLICY_TYPE_ATTACHMENT_LIMIT_EXCEEDED" || fail "$ERROR"
fi

echo "=== クリーンアップ ==="
for PID in "${POLICY_IDS[@]}"; do
  aws organizations detach-policy --policy-id "$PID" --target-id "$OU_ID" --region "$REGION" 2>/dev/null || true
  sleep 0.5
  aws organizations delete-policy --policy-id "$PID" --region "$REGION"
  sleep 0.5
done
aws organizations delete-organizational-unit --organizational-unit-id "$OU_ID" --region "$REGION"

echo "=== Part 2: ポリシーサイズ上限テスト ==="
python3 -c "
import json
cidrs = [f'10.{i}.{j}.0/24' for i in range(50) for j in range(256)]
policy = {'Version':'2012-10-17','Statement':[{'Sid':'Test','Effect':'Deny','Action':'*','Resource':'*','Condition':{'NotIpAddress':{'aws:SourceIp':cidrs}}}]}
compact = json.dumps(policy, separators=(',',':'))
while len(compact) > 10240:
    cidrs.pop()
    policy['Statement'][0]['Condition']['NotIpAddress']['aws:SourceIp'] = cidrs
    compact = json.dumps(policy, separators=(',',':'))
with open('/tmp/scp-max.json','w') as f: f.write(compact)
cidrs.append(f'10.{len(cidrs)//256}.{len(cidrs)%256}.0/24')
policy['Statement'][0]['Condition']['NotIpAddress']['aws:SourceIp'] = cidrs
with open('/tmp/scp-over.json','w') as f: f.write(json.dumps(policy, separators=(',',':')))
print(f'Max: {len(compact)} chars ({len(cidrs)-1} CIDRs), Over: {len(json.dumps(policy, separators=(chr(44),chr(58))))} chars ({len(cidrs)} CIDRs)')
"

if PID=$(aws organizations create-policy --name "SCP-SizeTest-Max" --description "Size test" \
  --type SERVICE_CONTROL_POLICY --content file:///tmp/scp-max.json \
  --region "$REGION" --query 'Policy.PolicySummary.Id' --output text 2>&1); then
  pass "上限以内のポリシー作成成功"
  aws organizations delete-policy --policy-id "$PID" --region "$REGION"
else
  fail "$PID"
fi

if ERROR=$(aws organizations create-policy --name "SCP-SizeTest-Over" --description "Size test over" \
  --type SERVICE_CONTROL_POLICY --content file:///tmp/scp-over.json \
  --region "$REGION" 2>&1); then
  fail "上限超過がエラーにならなかった"
else
  echo "$ERROR" | grep -q "POLICY_CONTENT_LIMIT_EXCEEDED" && \
    pass "上限超過でエラー: POLICY_CONTENT_LIMIT_EXCEEDED" || fail "$ERROR"
fi

echo "=== 全検証完了 ==="

Summary

The SCP attachment limit and the policy size have each doubled. There is no impact on existing SCP configurations, and because AWS Organizations is a global service, you can use the new quotas without any action on the user's side. It is now easier to design with SCPs separated by purpose, and the policy size constraint has also been eased. However, if you manage SCPs with the CLI/SDK, whitespace is counted toward the character count as is, so we recommend saving them as compact JSON.

References


そのCCoE、つくって終わりになっていませんか

ガバナンスのルールも組織ポリシーも、整えた直後はちゃんと機能する。でも運用が属人化すれば、CCoEはいつのまにか形だけに。ベンダー依存から内製へ踏み出すために、中の人として実行まで伴走する。立ち上げと定着の進め方を、無料資料にまとめました。

CCoE総合支援

CCoE立ち上げ資料をダウンロード

Share this article

AWSのお困り事はクラスメソッドへ