# Huawei Cloud Cdn Abnormal Status Code Analysis

> Diagnose CDN business abnormal HTTP status codes (4xx/5xx) using hcloud CLI.

Diagnose CDN business abnormal HTTP status codes (4xx/5xx) using hcloud CLI. Discover and quantify 4xx/5xx volume, localize the exact status code and time window, fork edge-generated vs origin-generated via back-to-source status statistics, correlate top-N distribution, narrow root cause on CDN edge config or origin side, and取证 per-request access logs.
Use this skill when the user wants to: (1) diagnose CDN abnormal 4xx/5xx status codes, (2) root-cause a 403/404/5xx spike on a CDN domain, (3) tell whether abnormal codes are generated by the CDN edge or returned by the origin, (4) troubleshoot CDN business exception status codes during daily inspection or incidents.
Triggers include: 状态码异常, 业务异常码, 4xx, 5xx, 403, 404, 502, 503, 504, status code, abnormal status, CDN异常, 边缘/回源, 限流, status code analysis, edge vs origin

- Page: https://ss33.ai/skills/huaweicloud/huawei-cloud-cdn-abnormal-status-code-analysis-39378126540
- Publisher: huaweicloud
- Category: [Software Development](https://ss33.ai/skills/category/software-development-t44z8z) › [DevOps & cloud](https://ss33.ai/skills/category/software-development-t44z8z/devops-and-cloud-unkt50)
- License: MIT
- Source: https://github.com/huaweicloud/huaweicloud-skills/blob/d0e2ed0da76827603f1d75bed8578c69c40b576c/skills/edge/cdn/huawei-cloud-cdn-abnormal-status-code-analysis/SKILL.md

## Skill

SKILL.md: https://ss33.ai/api/v1/ss33/download/huaweicloud/huawei-cloud-cdn-abnormal-status-code-analysis-39378126540

# CDN Abnormal Status Code Analysis

## Overview

This skill diagnoses **abnormal HTTP status codes (4xx / 5xx)** on a Huawei Cloud CDN accelerated domain.
It is **read-only** end to end: every action is a query (GET statistics / GET config / GET log-download-link / read-only log fetch).
It answers four questions for any 4xx/5xx anomaly:

1. **Is there an anomaly, and how big?** — quantify 4xx/5xx volume and ratio over a window.
2. **Which exact code, when, edge or origin?** — drill to the specific code + time bucket, and fork **edge-generated vs origin-generated** via the back-to-source (`bs_*`) status statistics.
3. **Who / where / what path?** — top IPs/paths/UA/referer, client IP count (刷量 vs real users).
4. **Root cause + forensics?** — narrow to edge-config rules or origin-side issues, then pin the exact requests via access logs.

**Key Features:**

- Edge-vs-origin fork driven by one command (`bs_status_code_*`): `result={}` ⇒ edge-generated; non-empty ⇒ origin-generated.
- Covers the full 4xx/5xx set: 400/401/403/404/405/406/408/410/412/416/429/499/495/496/500/501/502/503/504/505/530….
- Read-only log helper `scripts/fetch_cdn_log.py` downloads + decompresses a CDN log and extracts the abnormal-status rows as JSON.
- Structured diagnosis report with a status-code → root-cause decision tree and console/工单 remediation boundary (no CLI write ops).

**Tools**: hcloud CLI (KooCLI) + Python log helper (`scripts/fetch_cdn_log.py`).
**Core Principle**: Read-only diagnosis; **no configuration changes**.

## Triggers

Use when the user input matches any of the following (**user-phrase level**, bilingual):

| Language | Trigger examples (user phrasing) |
|----------|----------------------------------|
| 中文 | 「CDN 域名 403 突然变多，帮我查一下」「为什么最近一直 502」「4xx/5xx 状态码异常分析」「这个问题是边缘还是回源？帮忙区分一下」「业务异常码排查」「CDN 限流/封禁排查」「状态码异常」 |
| English | "403 spike on my CDN domain" / "root-cause a 5xx burst" / "status code analysis" / "is this edge or origin?" / "abnormal status codes during daily inspection" |

Keyword triggers (also in the frontmatter `description`): 状态码异常, 业务异常码, 4xx, 5xx, 403, 404, 502, 503, 504, status code, abnormal status, CDN异常, 边缘/回源, 限流, status code analysis, edge vs origin.

## Near-miss / Do NOT use

Do **NOT** use this skill when:

| Scenario | What to do instead |
|----------|--------------------|
| The domain is not onboarded to Huawei Cloud CDN | Confirm CDN onboarding / domain existence first; non-CDN HTTP issues are out of scope |
| The user wants to **change CDN config / refresh / preheat / ban URLs / enable-disable domains** | **Refuse** — this skill is read-only; guide to the CDN console or manual hcloud CLI (see [Prohibited Operations](#-prohibited-operations-security-constraints)) |
| Pure bandwidth / traffic analysis with **no status-code focus** | Not this skill's scope (no 4xx/5xx anomaly to explain) |
| User pastes AK/SK or asks to configure credentials in chat | **Refuse** — see [Authentication](#authentication); emit the secure setup template and wait |
| Non-CDN business exceptions (ECS / ELB / OBS / application-layer issues unrelated to CDN semantics) | Redirect to the relevant service skill |

## ⛔ Prohibited Operations (Security Constraints)

> This skill strictly prohibits **all non-GET (write/modify/delete) CDN operations**, even if requested by the user.

**Total: 55 prohibited operations** (24 POST + 25 PUT + 6 DELETE).

For the complete list of all 55 prohibited non-GET operations with risk descriptions, see [references/prohibited-operations.md](references/prohibited-operations.md).

**Representative prohibited operations (full list in the reference doc):**

| Prohibited Operation | Example CLI | Reason |
|----------------------|-------------|--------|
| ❌ Create domain | `CreateDomain` (v1/v2), `CreateDomainByDuplicate` | Write op, creates production resource |
| ❌ Delete domain | `DeleteDomain` (v1/v2) | Irreversible |
| ❌ Modify domain config | `hcloud CDN UpdateDomainFullConfig` / `UpdateBlackWhiteList` / `UpdateRefer` / `UpdateResponseHeader` / `UpdateOriginHost` / `UpdateCacheRules` / `UpdateHttpsInfo` | Write op, affects production traffic |
| ❌ Enable / disable domain | `EnableDomain` (v1/v2), `DisableDomain` (v1/v2) | Write op, affects production traffic |
| ❌ Refresh / preheat | `hcloud CDN CreateRefreshTasks` / `CreatePreheatingTasks` | Write op, changes cache |
| ❌ Modify billing mode | `SetChargeModes` | Financial impact |
| ❌ Verify domain owner | `hcloud CDN VerifyDomainOwner` | Write op |
| ❌ Set stats config / export open | `SetStatsConfig` / `ExportStatsOpen` | Write op |

> If the user requests a prohibited operation, refuse and inform:
> "Per security constraints, this skill performs read-only diagnosis only and does not run any write/delete operations.
> To change CDN configuration, use the Huawei Cloud CDN console or run the relevant hcloud command manually — this skill will not execute it.
> The complete list of 55 prohibited operations is documented in references/prohibited-operations.md."

## Architecture

```
CDN Abnormal Status Code Analysis (read-only)
├── ListDomains/v2                       (target domain → domain_id)
├── ShowDomainStats/v2
│   ├── summary  http_code_2xx..5xx + req_num    → quantify 4xx/5xx volume + ratio
│   └── detail   status_code_4xx/5xx             → exact code + time array
├── ShowDomainStats/v2  bs_status_code_4xx/5xx    → ★ edge vs origin fork ★
├── ShowBandwidthCalc / ListDomainClientStats      → traffic-spike / 刷量 correlation
├── Top-N family                                    → who / where / what path
├── Root cause fork
│   ├── origin side: ShowOriginHost / ShowDomainDetail / ShowHistoryTasks / TopOriginUrl
│   └── edge side:   ShowDomainFullConfig / ShowRefer / ShowBlackWhiteList /
│                    ListRuleDetails / ListBanUrl / ListAccessControlTask /
│                    ShowResponseHeader / ShowCertificatesHttpsInfo
├── ShowLogs/v2 + python scripts/fetch_cdn_log.py  → per-request forensics (JSON)
├── ShowIpInfo/v2                                   → client/edge IP attribution
└── generate diagnosis report
```

### API Call Budget

| Step | API / Script | Rate Limit | Est. Time |
|------|--------------|-----------|-----------|
| 1 | `hcloud CDN ListDomains/v2 --cli-region={region}` | — | <2s |
| 2 | `hcloud CDN ShowDomainStats/v2 --cli-region={region}` (summary + detail + bs) | 5/s | <3s |
| 3 | Top-N family + `ListDomainClientStats` | 2-5/s | <5s |
| 4 | `hcloud CDN ShowDomainFullConfig/v2 --cli-region={region}` + Show* config | — | <5s |
| 5 | `hcloud CDN ShowLogs/v2 --cli-region={region}` + `python scripts/fetch_cdn_log.py` | — | ≤ 30s |

**Total estimated time**: < 45 seconds (log-heavy window may be longer).

## KooCLI Command Format Standard

```bash
hcloud CDN <Operation> --cli-region=<region> [--key=value ...]
```

- **Service name**: `CDN` (uppercase). Operation name: PascalCase (e.g., `ShowDomainStats/v2`).
- **Region parameter**: `--cli-region=<region>`. CDN supports `cn-north-1` (Beijing) and `ap-southeast-1` (Singapore); results are region-independent.
  **Recommended: `cn-north-1` uniformly.** (`cn-north-4` is NOT supported by CDN.)
- **Parameter format**: `--key=value` (equals sign, no spaces). Space-separated form is unsupported.
- **Output**: append `--cli-output=json` for machine parsing.

## Prerequisites

> **Pre-check: hcloud (KooCLI) >= 3.2.0** — `hcloud version`. If missing, see [references/cli-installation-guide.md](references/cli-installation-guide.md).

> **Pre-check: Python >= 3.8** — `python --version`. Required by `scripts/fetch_cdn_log.py`.

> **Pre-check: Python `requests >= 2.25`** — `python -c "import requests; print('ok')"`. The log helper downloads via `requests`.
> Install if missing: `pip install requests>=2.25`

> **Pre-check: hcloud credentials** — `hcloud configure list`. If invalid, stop and guide secure configuration. Never read/echo/print AK/SK; never ask the user to paste AK/SK in chat.

> **⚠️ hcloud parameter format**: all params must use `--key=value`.

> **⚠️ CDN region**: use `cn-north-1` uniformly (CDN does not support `cn-north-4`).

> **⚠️ Time / interval rules**: time = ms timestamp, `[start,end)` left-closed right-open;
> `interval=300` (≤2d, 5-min points) / `3600` (≤7d, hour points) / `86400` (≤31d, **CST 0:00 points**).
> `status_code_*` (edge) and `bs_status_code_*` (origin) **cannot be mixed in one query**.

## Authentication

- **Prohibited**: reading/echoing/printing AK/SK; asking users to input AK/SK in chat; `hcloud configure set` with plaintext; accepting AK/SK pasted by the user.
- **Allowed**: read credentials from environment variables or the active CLI profile only.
- If the user pastes AK/SK, stop, refuse, and emit the secure setup template (`export HUAWEICLOUD_SDK_AK=...` / `HUAWEICLOUD_SDK_SK=...`), then wait.
- Verify: `hcloud configure list` — confirm a valid profile exists; if not, stop.

## IAM Permission Policies

See [references/iam-policies.md](references/iam-policies.md). Minimum: `cdn:*:query*` (plus `cdn:configuration:queryDomains`) and `cdn:log:*` for log forensics.
This skill is strictly read-only: no create / update / delete / refresh / ban permission is required or included.

## Core Commands

| Command | Purpose | Key Parameters |
|---------|---------|----------------|
| `hcloud configure list` | Check credentials | none |
| `hcloud CDN ListDomains/v2 --cli-region=<region>` | List domains → domain_id | — |
| `hcloud CDN ShowDomainStats/v2 --cli-region=<region> --action=summary\|detail --domain_name=<d> --stat_type=<t> --start_time=<ms> --end_time=<ms> --interval=<s>` | Quantify / localize status codes | `--action`, `--stat_type`, `--interval` |
| `hcloud CDN ShowBandwidthCalc --cli-region=<region> --domain_name=<d> --calc_type=bw_peak --start_time=<ms> --end_time=<ms>` | Bandwidth peak (traffic-spike correlation) | `--calc_type` |
| `hcloud CDN ListDomainClientStats --cli-region=<region> --domain_name=<d> --stat_type=ip_num --start_time=<ms> --end_time=<ms>` | Client IP count (刷量 vs real users) | `--stat_type=ip_num` |
| `hcloud CDN ListCdnDomainTopIps --cli-region=<region> --domain_name=<d> --stat_type=req_num --start_time=<ms> --end_time=<ms>` | Top-N drill (TopIps; same form for Path/OriginUrl/Refers/Uas; req_num only, no status) | `--stat_type=req_num` |
| `hcloud CDN ShowDomainFullConfig/v2 --cli-region=<region> --domain_name=<d>` | Full edge config (auth/refer/ip_filter/ua/…) | — |
| `hcloud CDN ShowRefer --cli-region=<region> --domain_id=<id>` | Referer防盗链 config | `--domain_id` |
| `hcloud CDN ShowBlackWhiteList --cli-region=<region> --domain_id=<id>` | IP blacklist/whitelist | `--domain_id` |
| `hcloud CDN ListRuleDetails --cli-region=<region> --domain_name=<d>` | Rule engine block rules | — |
| `hcloud CDN ListBanUrl --cli-region=<region> --start_time=<ms> --end_time=<ms> --page_number=1 --page_size=50` | Banned URLs (may need工单 whitelist) | time range |
| `hcloud CDN ListAccessControlTask --cli-region=<region> --start_time=<ms> --end_time=<ms> --limit=100` | Ban/unban tasks (may need工单 whitelist) | time range |
| `hcloud CDN ShowOriginHost --cli-region=<region> --domain_id=<id>` | 回源HOST | `--domain_id` |
| `hcloud CDN ShowResponseHeader --cli-region=<region> --domain_id=<id>` | Response header / error-page config | `--domain_id` |
| `hcloud CDN ShowDomainDetail --cli-region=<region> --domain_id=<id>` | Domain detail (origin/status/CNAME) | `--domain_id` |
| `hcloud CDN ShowHistoryTasks/v2 --cli-region=<region> --file_type=file --page_number=1 --page_size=50` | Refresh/preheat history | — |
| `hcloud CDN ShowCertificatesHttpsInfo/v2 --cli-region=<region> --domain_name=<d>` | HTTPS cert (49x/TLS) | `--domain_name` |
| `hcloud CDN ShowLogs/v2 --cli-region=<region> --domain_name=<d> --start_time=<ms> --end_time=<ms> --page_size=100` | Log download links (single domain, ≤30 days) | `--domain_name` |
| `python scripts/fetch_cdn_log.py --url <link> [--status 403,502,503,504] [--timeout 30] [--max-lines 200]` | Fetch+decompress log, extract abnormal rows (emits JSON) | `--url`, `--status` |
| `hcloud CDN ShowIpInfo/v2 --cli-region=<region> --ips=<ip1>,<ip2>` | IP attribution (≤20) | `--ips` |

> Top-N family `stat_type` supports only `flux`/`req_num` (no status code) — cross-reference with `ShowDomainStats`/logs.

## Parameter Confirmation

| Parameter | Required | Description | Default | Example |
|-----------|----------|-------------|---------|---------|
| `domain_name` | Yes | CDN accelerated domain to diagnose | — | `www.example.com` |
| `domain_id` | Yes (for some Show* by-id ops) | From `ListDomains/v2` | — | `d3aaa521…` |
| `--cli-region` | Yes | CDN region | `cn-north-1` | `cn-north-1` |
| time window | Yes | `[start,end)` ms timestamps, aligned to interval points | — | last 7 days |
| `--status` (log helper) | No | Status codes to extract | `403,404,499,500,502,503,504,530` | `403,502` |

**User confirmation checklist:**

- [ ] Target domain provided
- [ ] User understands this is read-only diagnosis
- [ ] User understands log fetch has a 30s timeout

## Core Workflows

> **Target domain is required before any diagnosis step.**
>
> - If the user did not provide a target domain, ask the user for the domain name and wait for the reply before starting.
> - Only if the user does not know the domain or asks you to look it up, list the account's domains via `hcloud CDN ListDomains/v2` and ask the user to choose one.
> - Never start the diagnosis without an explicit user-provided domain: do not guess a domain, do not fall back to an example/default domain, and do not pick a domain from the list yourself.

### Step 1: Discovery & Quantification — find 4xx/5xx, size, traffic correlation

📄 Detailed steps → [references/task-discovery.md](references/task-discovery.md)

### Step 2: Localize & Fork — exact code + time + edge/origin

📄 Detailed steps → [references/task-localize.md](references/task-localize.md)

### Step 3: Distribution — top-N + client-IP count

📄 Detailed steps → [references/task-distribution.md](references/task-distribution.md)

### Step 4: Root Cause — origin side (4A) / edge side (4B) per Step 2 fork

📄 Detailed steps → [references/task-rootcause.md](references/task-rootcause.md)

### Step 5: Per-request Forensics — log fetch + IP attribution

📄 Detailed steps → [references/task-forensics.md](references/task-forensics.md)

### Step 6: Report — decision tree + remediation boundary

📄 Detailed steps → [references/task-report.md](references/task-report.md)

## FAQ (Q&A)

> Detailed troubleshooting and the full error-code reference are in [references/troubleshooting.md](references/troubleshooting.md).

### Q1: Why do ListBanUrl / ListAccessControlTask return CDN.0004?

A: These two query APIs require a 工单 (support-ticket) whitelist; they are still query-class GET operations.
Record the error, do not bypass, continue with the other evidence, and mark "unconfirmed via CLI" in the report.

### Q2: Why does ShowDomainStats return an empty result?

A: No traffic in the window, the status code did not occur, or the timestamps are not aligned to the interval
(`interval=86400` requires CST 0:00 points). Widen the window (e.g. 31 days), align the time points,
and confirm the domain had traffic, then retry.

### Q3: Can `status_code_*` and `bs_status_code_*` be combined in one query?

A: **No.** Edge and back-to-source statistics must be run as two separate `ShowDomainStats/v2` calls.

### Q4: Why is there no status code in the Top-N results?

A: The Top-N family (TopIps/Path/OriginUrl/Refers/Uas) `stat_type` supports only `flux`/`req_num` — there is
no status-code dimension. Use Top-N to shortlist suspect IPs/paths, then cross-check the actual status codes
via `ShowLogs` / `ShowDomainStats`.

### Q5: Why does ShowLogs return logs: [] / total: 0?

A: No log file covers the window, the window is not left-closed right-open / hour-aligned, or the domain
had no traffic in that period. Align to whole-hour CST points, widen the window, and confirm traffic, then retry.

### Q6: How do I handle fetch_cdn_log.py errors?

A: See the error-code table in [references/troubleshooting.md](references/troubleshooting.md) (9 `error.reason` values:
`connect_timeout` / `connect_failed` / `http_error` / `bad_gzip` / `invalid_url` / `invalid_timeout` /
`invalid_max_lines` / `invalid_status` / `missing_library`). Soft failures exit 0 (JSON `error` included),
argument/missing-library errors exit 2. Common fixes: raise `--timeout` (≤60), re-run `ShowLogs/v2` to
refresh an expired link, or `python -m pip install requests>=2.25`.

### Q7: Why does a CDN query return 403 Insufficient permission?

A: The IAM user lacks the CDN read-only scope. Grant `cdn:*:query*` (plus `cdn:configuration:queryDomains`
and `cdn:log:*` for log forensics) per [references/iam-policies.md](references/iam-policies.md).
**Never elevate to any write action.**

### Known Issues and Limitations

| Limitation | Description |
|------|------|
| `ShowLogs/v2` | Single domain only; span ≤ 30 days |
| Top-N `stat_type` | Only `flux`/`req_num`; no status-code dimension (cross-check required) |
| `ListDomainClientStats` | `ip_num` supports 1-day granularity only (CST 0:00); the unique-visitor metric supports 5-min granularity |
| `ListBanUrl` / `ListAccessControlTask` | Require a 工单 (support-ticket) whitelist (`CDN.0004`); record and continue |
| Log parsing | `fetch_cdn_log.py` parses the official Huawei Cloud 14-field log format; fields containing spaces (time, user_agent) are kept as one token / quoted ([official doc](https://support.huaweicloud.com/intl/zh-cn/bestpractice-cdn/cdn_01_0252.html)) |
| CDN region | Only `cn-north-1` / `ap-southeast-1`; `cn-north-1` recommended uniformly; `cn-north-4` is not supported |

### Error Code Quick Reference

| Error | Meaning | Action |
|-------|---------|--------|
| `CDN.0004` | Not in the 工单 whitelist (`ListBanUrl` / `ListAccessControlTask`) | Record, continue, mark "unconfirmed via CLI" |
| `cli-region的值不支持` | Region not supported by CDN | Use `--cli-region=cn-north-1` (or `ap-southeast-1`) |
| `403 Insufficient permission` | IAM lacks the CDN read-only scope | Grant `cdn:*:query*` (+ `cdn:log:*`); never elevate |

## Failure Modes

> Detailed troubleshooting is in [references/troubleshooting.md](references/troubleshooting.md). Each task step's **Exit criteria** is the self-check.

### Known failure modes and recovery strategy

| Failure mode | Symptom | Recovery strategy (retry / fallback / degrade / report) |
|----------|------|----------|
| Region not supported | `cli-region的值不支持`, only cn-north-4/ru-moscow-1 hinted | Switch to `--cli-region=cn-north-1` (or `ap-southeast-1`) |
| CDN.0004 whitelist | `ListBanUrl` / `ListAccessControlTask` return "not in the whitelist" | **Degrade**: record unconfirmed via CLI, continue with other evidence, mark it in the report; do not bypass |
| Empty result | `ShowDomainStats` returns `{}` | **Retry**: widen the window (31 days), align to the interval points (CST 0:00 for 86400), confirm traffic |
| Edge/origin mixed query | Passing `status_code_*` and `bs_status_code_*` together errors | Split into two `ShowDomainStats/v2` calls |
| Top-N has no status codes | Top-N returns request counts only | **Cross-check**: confirm the actual codes via `ShowLogs` / `ShowDomainStats` |
| ShowLogs returns no links | `logs: []` / `total: 0` | **Retry**: align to whole-hour CST points, widen the window, confirm traffic in the window |
| Log download failure | `fetch_cdn_log.py` `error.reason` = connect_timeout / connect_failed / http_error / bad_gzip | **Retry / refresh**: raise `--timeout` (≤60), re-run `ShowLogs/v2` to refresh the expired link, check gzip |
| Permission denied | Query returns 403 Insufficient permission | Check the IAM read-only scope (`cdn:*:query*` + `cdn:log:*`); **never elevate to write actions** |

### Error propagation and handling protocol (fetch_cdn_log.py)

- **exit 0**: probe ran to completion (including soft failures — HTTP non-200, empty result, bad gzip, timeout); emits JSON `error.reason` for the caller.
- **exit 2**: argument error or missing dependency library (`requests`).
- `error.reason` enum (9 values): `connect_timeout` / `connect_failed` / `http_error` / `bad_gzip` / `invalid_url` / `invalid_timeout` / `invalid_max_lines` / `invalid_status` / `missing_library`.

### Self-check before output

- [ ] Does the report contain all required sections (Summary / Distribution / Root Cause / Conclusion / Remediation boundary)?
- [ ] Does every claim have evidence (config state / bs verdict / log rows / rule list)?
- [ ] Are unconfirmed items (e.g. blocked by CDN.0004) marked "unconfirmed via CLI"?
- [ ] Does the report avoid recommending any write operation to be executed by this skill? (**must** be yes)

## Output Format

This skill has two output contracts.

### 1. Diagnosis report (plain text)

Report template: [references/task-report.md](references/task-report.md). Required sections and fields:

| Section | Required fields |
|---------|----------|
| Header | Analysis Time (ISO8601), Target Domain, Region |
| Summary | Abnormal status-code set, anomaly window (CST), volume / ratio, edge-origin verdict (`bs_status_code_<X>` empty → edge / non-empty → origin) |
| Distribution | Top IP/URL/UA/Referer, client verdict (few-IP burst / many real users, with ip_num/req_num), bandwidth peak |
| Root Cause | Candidate mechanism, evidence, ruled-out items, unconfirmed-via-CLI items |
| Conclusion | Status (Edge-generated / Origin-generated / Partial), suggestion, remediation boundary (write ops only via the CDN console or manual hcloud CLI) |

### 2. fetch_cdn_log.py JSON (structured)

Schema: [references/related-apis.md](references/related-apis.md). Top-level fields:

| Field | Type | Description |
|------|------|------|
| `url` | string | Log download link |
| `http_status` | int | Download HTTP status |
| `byte_size` | int | Downloaded bytes |
| `status_filter` | int[] | Status-code filter set |
| `rows[]` | object[] | Matched rows (field enum: `status`(int 100-599), `cache_status`(HIT/MISS), `time`, ...), incl. `client_ip`, `url`, `user_agent`, `edge_node_ip` |
| `count` | int | Number of matched rows |
| `duration_ms` | int | Elapsed time |
| `error` | object/null | `null` or `{reason, message}` (reason enum — see [Failure Modes](#failure-modes)) |

### Output example (fetch_cdn_log.py JSON excerpt)

```json
{"status":403,"client_ip":"120.46.140.45","url":"/index.html","cache_status":"HIT","user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64)","edge_node_ip":"39.136.130.12","time":"[10/Aug/2026:15:55:13 +0800]"}
```

### Content to NEVER include in the output

- AK/SK and any credentials (see [Authentication](#authentication))
- Internal / sensitive addresses and customer private information (output only the fields needed for diagnosis)
- The raw full log text (output only the extracted rows fields)
- Conclusions beyond the evidence (unconfirmed items must be marked "unconfirmed")

## References

| Document | Description |
|----------|-------------|
| [task-discovery.md](references/task-discovery.md) | Step 1: discovery & quantification |
| [task-localize.md](references/task-localize.md) | Step 2: localize exact code + edge/origin fork |
| [task-distribution.md](references/task-distribution.md) | Step 3: top-N/client distribution |
| [task-rootcause.md](references/task-rootcause.md) | Step 4: origin-side (4A) / edge-side (4B) root cause |
| [task-forensics.md](references/task-forensics.md) | Step 5: per-request log forensics |
| [task-report.md](references/task-report.md) | Step 6: diagnosis report + decision tree |
| [prohibited-operations.md](references/prohibited-operations.md) | All 55 prohibited non-GET operations (POST/PUT/DELETE) |
| [dataflow-diagram.md](references/dataflow-diagram.md) | Mermaid data flow diagram |
| [related-apis.md](references/related-apis.md) | API/CLI reference + stat_type + status-code map |
| [iam-policies.md](references/iam-policies.md) | IAM least-privilege policies |
| [verification-method.md](references/verification-method.md) | Verification method |
| [acceptance-criteria.md](references/acceptance-criteria.md) | Acceptance criteria checklist |
| [troubleshooting.md](references/troubleshooting.md) | Troubleshooting |
| [cli-installation-guide.md](references/cli-installation-guide.md) | CLI installation guide |

## Changelog / Version History

| Version | Date | Maintainer | Changes |
|------|------|--------|----------|
| v1.0.0 | 2026-08-10 | cdn-ops | Initial release: read-only 6-step diagnosis workflow (discovery / localize / distribution / root-cause / forensics / report), 55 prohibited operations, `fetch_cdn_log.py` log-forensics helper, 14 reference documents |

> Versioning follows SemVer (`major.minor.patch`); current frontmatter `version: 1.0.0`. Append a row to the
table and bump the frontmatter `version` on every major change.
> Maintainer: `cdn-ops`. If a CDN query API this skill depends on (e.g. `ShowLogs/v2`, `bs_status_code_*`
statistics) is **deprecated / sunset** or changes behavior, update [references/related-apis.md](references/related-apis.md)
and [references/troubleshooting.md](references/troubleshooting.md) accordingly.
