Windows vs Linux App Service Behavioral Differences¶
Status: Draft - Awaiting Execution
Experiment designed. Awaiting execution across both Windows and Linux App Service plans.
1. Question¶
What are the observable behavioral differences between Windows and Linux App Service plans for the same application workload? Which differences are diagnostic traps — cases where a behavior expected on one platform is silently different on the other?
2. Why this matters¶
Many App Service support cases originate from unexpected behavior when an application is migrated from Windows to Linux (or vice versa), or when support engineers apply debugging techniques specific to one platform to the other. Critical differences in file system case sensitivity, environment variable availability, diagnostic endpoint behavior, and container model affect both debugging and application correctness.
3. Customer symptom¶
- "The app works on Windows but fails on Linux — same code, same settings."
- "I can't find the App Service Editor on Linux."
- "On Linux,
WEBSITE_CONTENTAZUREFILECONNECTIONSTRINGdoesn't work." - "Windows shows me the process list in Kudu but Linux doesn't."
- "File paths work differently — some files are missing on Linux."
4. Hypothesis¶
H1 — Filesystem case sensitivity: Linux App Service uses a case-sensitive filesystem. Windows uses case-insensitive NTFS. Code with inconsistent file path casing works on Windows and fails on Linux.
H2 — Environment variable differences: Certain WEBSITE_* and APPSETTING_* environment variables are injected differently or not at all on Linux vs. Windows. The APPSETTING_ prefix wrapper present on Windows is absent on Linux.
H3 — Kudu surface differences: Kudu on Windows provides the App Service Editor, Process Explorer, and CMD console. Kudu on Linux provides SSH (Bash shell) only — no App Service Editor, no Process Explorer.
H4 — IIS presence: Windows App Service runs IIS as the reverse proxy; Linux runs a custom proxy (Oryx/custom container). X-ARR-SSL, X-Original-URL, and certain IIS-specific headers are Windows-only.
H5 — Startup command differences: On Linux, the STARTUP_FILE or startupCommand setting specifies the entrypoint. On Windows, web.config controls IIS HTTP handler mapping. The same app requires different startup configuration on each platform.
5. Environment¶
| Parameter | Value |
|---|---|
| Service | App Service |
| SKU / Plan | B1 Windows vs B1 Linux (same region) |
| Region | Korea Central |
| Runtime | Python 3.11 (both) |
| Date tested | Not yet executed |
6. Variables¶
Experiment type: Platform Comparison
Controlled:
- Application code (identical Python Flask app deployed to both)
- App settings (identical values on both)
- SKU tier (B1 on both)
Observed:
- Environment variables present on each platform
- Kudu feature availability
- HTTP headers injected by the platform
- Filesystem case sensitivity behavior
- Startup command requirements
7. Instrumentation¶
- Diagnostic endpoint:
GET /envdumps all environment variables - Header endpoint:
GET /headersdumps all request headers - File test endpoint:
GET /file-testattempts bothREADME.mdandreadme.md - Kudu API:
https://<app>.scm.azurewebsites.net/api/diagnostics/processes(Windows) vs. SSH Bash (Linux)
8. Procedure¶
8.1 Infrastructure Setup¶
# Windows plan
az appservice plan create --name plan-win --resource-group rg-platform-diff \
--sku B1 --location koreacentral
az webapp create --name app-win-diff --resource-group rg-platform-diff \
--plan plan-win --runtime "PYTHON:3.11"
# Linux plan
az appservice plan create --name plan-linux --resource-group rg-platform-diff \
--sku B1 --location koreacentral --is-linux
az webapp create --name app-linux-diff --resource-group rg-platform-diff \
--plan plan-linux --runtime "PYTHON:3.11"
8.2 Scenarios¶
S1 — Environment variable comparison: Deploy identical app to both. Compare GET /env output. Identify variables present on one but not the other.
S2 — Header injection: Send HTTP request to both. Compare headers received by the application. Look for IIS-specific headers on Windows.
S3 — Case sensitivity: Create a file named Data.json. Attempt to open data.json (lowercase) via code. Observe success (Windows, case-insensitive) vs. failure (Linux, case-sensitive).
S4 — Kudu surface: Document available Kudu endpoints on each platform. Identify diagnostic capabilities exclusive to Windows.
S5 — Startup command: Deploy the same app with identical startupCommand. Observe whether both platforms interpret the command identically.
9. Expected signal¶
- S1: Windows injects
APPSETTING_*wrappers; Linux does not.WEBSITE_CONTENTAZUREFILECONNECTIONSTRINGis Windows-specific. - S2:
X-ARR-SSL,X-Original-URLpresent on Windows; absent or different on Linux. - S3:
data.jsonopen fails on Linux (FileNotFoundError); succeeds on Windows. - S4: App Service Editor unavailable on Linux Kudu. Process Explorer (Windows-only).
- S5:
startupCommandbehavior differs — Windows may require fullpython -m flask runwhile Linux uses it as Docker CMD override.
10. Results¶
Results pending execution
No data collected yet.
11. Interpretation¶
Awaiting results.
12. Limits¶
- Python runtime may behave differently from Node.js or .NET on the same platform — this experiment focuses on Python.
- Windows App Service on B1 tier uses shared workers; some behaviors may differ on dedicated tiers.
13. Confidence calibration¶
| Claim | Level |
|---|---|
| Linux filesystem is case-sensitive | Observed (well-documented) |
APPSETTING_ prefix differs between platforms |
Strongly Suggested |
| Kudu Process Explorer is Windows-only | Observed |
14. Related experiments¶
- Linux Windows Timezone — timezone handling differences
- Worker Bitness Mismatch — 32-bit vs 64-bit worker issues
- procfs Interpretation — Linux-specific /proc filesystem behavior
15. References¶
16. Support takeaway¶
When troubleshooting platform migration issues (Windows to Linux or vice versa):
- Always verify the platform with
WEBSITE_OS_NAMEor check Kudu — Windows Kudu has Process Explorer and App Service Editor; Linux Kudu has SSH only. - Filesystem case sensitivity is the most common silent breakage on Windows-to-Linux migration. Ask the customer to grep for mixed-case file references in their code.
APPSETTING_prefix wrappers exist on Windows but not Linux. Code that readsos.environ.get("APPSETTING_MY_KEY")works on Windows, fails silently on Linux.- IIS-specific headers (
X-ARR-SSL,X-Original-URL) are injected by IIS on Windows. Linux uses a different reverse proxy and these headers may not be present.