What Are IIS Logs? Formats, Fields, and Forensics
An IIS log is the access record Internet Information Services writes for a Windows web server, one line per HTTP request, capturing who connected, what they requested, and how the server answered.
Open the IIS log on a webshell-hit server and the compromise is usually right there in space-delimited text. A POST to /uploads/test.aspx returning 200, followed minutes later by a string of GET requests to that same .aspx carrying cmd=whoami in the URI query. One client IP. One user-agent that is not a browser. The IIS log does not raise an alarm about any of it. It writes one line per request and leaves the interpretation to you. That is why it is one of the first artifacts a responder pulls off a Windows web server.
An IIS log is the access record that Internet Information Services, the web server built into Windows Server, writes for every HTTP request it handles. It records who connected, what they asked for, how the server answered, and how long it took. This guide covers what IIS logs are, the three formats IIS can write, where the files live, the fields you will actually parse, and how a defender uses them in detection and forensics. It is written for the people who open these files under pressure: SOC analysts triaging an alert, threat hunters baselining a web tier, DFIR responders scoping an intrusion.
What is an IIS log?
IIS (Internet Information Services) is Microsoft's web server, shipped as a Windows Server role. When it serves a site, it appends one line per HTTP request to a log file, recording the request and the server's response. The unit is the request, not the visitor and not the session. A single page view produces many lines, one for the HTML document and one for each image, script, and stylesheet the browser then fetches.
By default IIS keeps a separate set of log files per website, so a server hosting several sites writes to several folders. Each line is written after IIS finishes handling the request, which makes the log an after-the-fact record of what happened, in the order it happened.
Like any access logs, the IIS log records requests whether or not they succeeded. A request that returned 404 Not Found, one blocked with 403 Forbidden, and one that returned 500 because it crashed the application all land in the file next to the requests that worked. For a defender that is the entire value. An attacker probing for a vulnerable handler leaves a trail of failures before the one request that lands, and those failures are the reconnaissance you need to see. A log that kept only successes would erase the hunt and hand you just the breach.
IIS logging is on by default for a site served through the IIS role. In Azure it varies by service: some platforms enable web server logging automatically, while Azure App Service requires you to turn it on. The practical lesson is the same one cloud responders learn the hard way: confirm the log exists for your incident window before you rely on it.
IIS log formats
IIS can write its access log in one of three text formats, plus a custom option. They differ in their delimiter, their time zone, and whether you can choose the fields. Knowing which format a server uses is the first thing you check, because it determines how you parse every line after.
| Format | Delimiter | Time | Fields | Notes |
|---|---|---|---|---|
| W3C Extended | Space | UTC | Customizable, you select them | The default. Carries a #Fields: header naming the columns |
| IIS | Comma | Local | Fixed, not customizable | Comma-separated, easy to load into a spreadsheet |
| NCSA Common | Space | Local with UTC offset | Fixed, not customizable | Basic request data only, matches the classic web log shape |
| Custom | Defined by module | Module-defined | Module-defined | For a custom logging module; not configurable in IIS Manager |
All three text formats are written as plain ASCII. The one you will meet most often is W3C Extended, because it is the default and because it is the only built-in format that lets an administrator pick the fields. A W3C file begins with directive lines, and the one that matters is #Fields:, which names every column in order. Never assume the columns: read the #Fields: header, because two W3C logs from two servers can carry different fields. W3C records time in UTC, which removes the time-zone guessing that complicates correlation.
The IIS format is a fixed, comma-delimited layout that records time in local server time. The fixed field set means you cannot add or drop columns, but the commas make it trivial to open in a spreadsheet or split on. The NCSA Common format is space-delimited, fixed, and uses local time with a UTC offset; it produces the same basic request shape as the classic web server log and carries less detail than a fully populated W3C line. All of these are handled by the kernel-mode HTTP.sys driver, not the worker process, which is why a request can be logged even when the application behind it never ran.
Where IIS logs are stored
The default log directory is %SystemDrive%\inetpub\logs\LogFiles, which on a typical server resolves to C:\inetpub\logs\LogFiles. Under that root, IIS creates one subfolder per website, named W3SVC followed by the site ID, so the first site is W3SVC1, the next W3SVC2, and so on. Map the site ID to the folder before you start reading, or you will analyze the wrong site's traffic.
Inside each subfolder, IIS rolls the log over on a schedule, daily by default, producing files named for the date such as u_ex260620.log for 20 June 2026 in UTC. Rollover can also be set to hourly, weekly, monthly, by maximum file size, or disabled so a single file grows without bound. The directory itself is configurable per site or per server, and a security-conscious admin will move it off the system volume. Two consequences for a responder: the path you are handed may not be the default, and the file you want may have already rolled, so collect the surrounding files, not just today's.
Contents of an IIS log
A W3C line is a sequence of fields whose meaning comes from the #Fields: header. IIS uses short, prefixed field names where the prefix tells you the direction: c- is client, s- is server, cs- is client-to-server (the request), and sc- is server-to-client (the response). These are the fields an investigation actually leans on.
| Field | W3C name | What it records | Why a defender cares |
|---|---|---|---|
| Client IP | c-ip | Address of the client that made the request | Pivot point: group by IP, match threat intel, spot one host hammering an endpoint |
| Date and time | date time | When the request was received, in UTC | Builds the timeline; correlates with other logs; reveals off-hours activity |
| Method | cs-method | HTTP verb (GET, POST, PUT) | POST to an upload path, PUT writing a file, unusual verbs |
| URI stem | cs-uri-stem | The resource path requested | What was targeted; a request to an unexpected .aspx is a webshell tell |
| URI query | cs-uri-query | The query string after the path | Where injection and command strings hide (cmd=, ../, SQL) |
| Status | sc-status | HTTP status code returned | 2xx worked, 4xx client error, 5xx server error; bursts of 4xx are recon |
| Substatus | sc-substatus | IIS substatus refining the status | 404.0 missing file vs 404.11 rejected by request filtering |
| Win32 status | sc-win32-status | Underlying Windows error code | Distinguishes why a request failed at the OS level |
| Username | cs-username | Authenticated user, a hyphen if anonymous | Ties a request to an account once authentication is in play |
| Bytes sent | sc-bytes | Size of the response | A large response on a small endpoint can flag data exfiltration |
| User agent | cs(User-Agent) | Client's self-reported software | Scanners and scripted tools announce themselves here |
| Referer | cs(Referer) | The page the request came from | Context on how a resource was reached |
| Time taken | time-taken | Request duration in milliseconds | Slow responses can mark heavy queries or exploitation |
Two IIS-specific fields earn extra attention. The substatus (sc-substatus) splits a single status code into causes: a plain 404.0 is a missing file, but 404.11 means request filtering rejected a double-escaped URL and 404.13 means the content length exceeded a limit, both of which are signals an attacker tripped a control. The Win32 status (sc-win32-status) carries the underlying Windows error, so a 401.1 with a specific Win32 code tells you whether a failed logon was a bad password or a disabled account. These two fields are why IIS logs often beat a generic web log for Windows incident response.
The status code carries more weight than its three digits suggest. Per RFC 9110, the current HTTP semantics specification, codes group into five classes by their first digit: 1xx informational, 2xx success, 3xx redirection, 4xx client error, and 5xx server error. In a hunt the distribution matters as much as any single code. A normal endpoint returns mostly 2xx. A run of 4xx from one IP is someone probing for things that do not exist or are not allowed. A spike in 5xx can mean an attacker found an input that breaks the application, often the first sign of a working exploit.
How defenders read IIS logs
IIS logs earn their keep across detection, forensics, and hunting, and turning the raw files into answers is the work of log analysis.
Detection. Patterns in IIS logs are signal. A brute-force or password-spray against an OWA or web login shows as many POSTs with a string of 401s from one or a few IPs. Web scanning shows as one source walking hundreds of paths, most returning 404. SQL injection and path traversal show as suspicious strings in cs-uri-query and cs-uri-stem. A webshell shows as repeated requests to an .aspx or .aspx that did not exist before the intrusion, often a POST to drop it followed by GETs carrying commands.
Forensics and incident response. After a confirmed intrusion the IIS log is how you scope it. Take the attacker's IP, user-agent, or the webshell path and pull every line that matches, which reconstructs the sequence: the probe, the upload, the commands run through the shell, and the size of each response. Because the log keeps failures, you also see the reconnaissance that came first, which often reveals what else the attacker tried and where else to look. The substatus and Win32 fields tell you which controls held and which gave way.
Baselining and threat hunting. Before you can spot the anomaly you have to know normal. IIS logs over time establish the baseline: which URIs get traffic, from which networks, at which hours, with which user-agents and methods. A hunt is then a search for deviation, a new admin handler suddenly receiving requests, a PUT where you only ever see GET, a user-agent belonging to no real client, a geography that never appeared before.
Feeding the SIEM. On their own these are flat files scattered across web servers. Collected, parsed on the #Fields: header, and normalized into a SIEM, they become queryable at scale and correlatable with the rest of your telemetry. A lone 200 on a login from a new IP means little until the SIEM ties it to a failed-login burst from the same source minutes earlier, or to a Windows logon event on the same host. That correlation is where a flat web log becomes an alert.
Reading an IIS log line in practice
Put it together on one W3C line. Assume the #Fields: header is date time c-ip cs-method cs-uri-stem cs-uri-query sc-status sc-substatus sc-bytes cs(User-Agent) and the line is:
2026-06-20 02:14:07 203.0.113.5 GET /uploads/shell.aspx cmd=whoami 200 0 4096 python-requests/2.31.0
Field by field: the date and time are just after 2 a.m. UTC. The client is 203.0.113.5. The method is GET, the URI stem is /uploads/shell.aspx, a script in an uploads directory that should hold images, not executable handlers. The query is cmd=whoami, an operating-system command passed to that handler. The server answered 200 with substatus 0 and sent 4096 bytes, so the request succeeded and returned output. The user-agent is python-requests/2.31.0, a scripted client, not a browser.
One line, and you have an IP to pivot on, a webshell path to grep across every other log, a confirmed command execution, and a tool fingerprint to hunt elsewhere. The line above it, a POST to the same /uploads/shell.aspx returning 201 or 200, is where the shell was planted. That pair, the upload and the first command, is the spine of a web intrusion, and the IIS log is where you read it.
Frequently Asked Questions
What is an IIS log?
An IIS log is the access record that Internet Information Services, the Windows Server web server, writes for the sites it hosts. It appends one line per HTTP request, capturing the client IP, the time, the requested resource, the HTTP method, the status code the server returned, and more. IIS records failed and blocked requests alongside successful ones, which is what makes the log valuable for spotting reconnaissance and attacks.
What are the IIS log file formats?
IIS can write three built-in text formats plus a custom option. W3C Extended is the default: space-delimited, UTC time, with fields you select and a #Fields: header naming them. The IIS format is comma-delimited with a fixed field set in local time. NCSA Common is space-delimited and fixed, using local time with a UTC offset. All are plain ASCII, and W3C is the one most defenders parse.
Where are IIS logs stored?
The default location is %SystemDrive%\inetpub\logs\LogFiles, usually C:\inetpub\logs\LogFiles. Under that root, IIS creates one subfolder per site named W3SVC plus the site ID, such as W3SVC1. By default a new log file rolls over each day with a date-based name like u_ex260620.log. The directory is configurable, so the path on a given server may differ from the default.
What fields are in an IIS log?
The common W3C fields are the date and time, client IP (c-ip), HTTP method (cs-method), the requested resource (cs-uri-stem) and query string (cs-uri-query), the status (sc-status) and substatus (sc-substatus), bytes sent (sc-bytes), the username (cs-username), the user agent (cs(User-Agent)), the referer (cs(Referer)), and the request duration (time-taken). The exact set depends on which fields the administrator selected, so read the #Fields: header.
How do attackers show up in IIS logs?
Common patterns include bursts of 401 responses from one IP (brute force or password spray), large numbers of 404s as a scanner walks the site, injection and traversal strings in cs-uri-query or cs-uri-stem, and requests to script handlers like an unexpected .aspx in an uploads folder, which is the classic webshell tell. Anomalous user-agents such as python-requests or sqlmap instead of real browsers, and unusually large sc-bytes responses, round out the signals.
What is the difference between an IIS log and a Windows event log?
An IIS log records HTTP requests to the web server, one line per request, in a text format like W3C. A Windows event log records system, security, and application events on the host, such as logon successes and failures (events 4624 and 4625), service starts, and audit changes, in the structured Windows Event Log store. In an investigation you correlate the two: the IIS log shows the web request, and the event log shows what happened on the host around it.
Are IIS logs enabled by default?
For a site served through the IIS role, web server logging is on by default and writes W3C files to the default directory. In the cloud it depends on the service: some Azure offerings enable web server logging automatically, while Azure App Service requires you to enable it. As with any logging, confirm it was on for the time window you need before an incident, because a log that was never written cannot be analyzed after the fact.
The bottom line
An IIS log is the per-request access record for a Windows web server, one line each, including the requests that failed. IIS writes it in one of three text formats, and the default, W3C Extended, is space-delimited, in UTC, with selectable fields named by a #Fields: header you must read before you parse. The files live under %SystemDrive%\inetpub\logs\LogFiles in per-site W3SVC folders and roll over daily by default.
For a defender the value is in what the log does not filter out. The scans, the failed probes, the blocked requests, and the one upload that finally worked all sit in the same file, in order, with IIS-specific substatus and Win32 codes telling you exactly why each one failed or passed. That is what turns the IIS log from a server-housekeeping file into the first thing you reach for when you need to know who hit the site, what they ran, and whether it worked. The only failure mode that matters is the log that was never written, so confirm logging is on and retained before you need it.
Frequently asked questions
<p>An IIS log is the access record that Internet Information Services, the Windows Server web server, writes for the sites it hosts. It appends one line per HTTP request, capturing the client IP, the time, the requested resource, the HTTP method, the status code the server returned, and more. IIS records failed and blocked requests alongside successful ones, which is what makes the log valuable for spotting reconnaissance and attacks.</p>
<p>IIS can write three built-in text formats plus a custom option. W3C Extended is the default: space-delimited, UTC time, with fields you select and a <code>#Fields:</code> header naming them. The IIS format is comma-delimited with a fixed field set in local time. NCSA Common is space-delimited and fixed, using local time with a UTC offset. All are plain ASCII, and W3C is the one most defenders parse.</p>
<p>The default location is <code>%SystemDrive%\inetpub\logs\LogFiles</code>, usually <code>C:\inetpub\logs\LogFiles</code>. Under that root, IIS creates one subfolder per site named <code>W3SVC</code> plus the site ID, such as <code>W3SVC1</code>. By default a new log file rolls over each day with a date-based name like <code>u_ex260620.log</code>. The directory is configurable, so the path on a given server may differ from the default.</p>
<p>The common W3C fields are the date and time, client IP (<code>c-ip</code>), HTTP method (<code>cs-method</code>), the requested resource (<code>cs-uri-stem</code>) and query string (<code>cs-uri-query</code>), the status (<code>sc-status</code>) and substatus (<code>sc-substatus</code>), bytes sent (<code>sc-bytes</code>), the username (<code>cs-username</code>), the user agent (<code>cs(User-Agent)</code>), the referer (<code>cs(Referer)</code>), and the request duration (<code>time-taken</code>). The exact set depends on which fields the administrator selected, so read the <code>#Fields:</code> header.</p>
<p>Common patterns include bursts of <code>401</code> responses from one IP (brute force or password spray), large numbers of <code>404</code>s as a scanner walks the site, injection and traversal strings in <code>cs-uri-query</code> or <code>cs-uri-stem</code>, and requests to script handlers like an unexpected <code>.aspx</code> in an uploads folder, which is the classic webshell tell. Anomalous user-agents such as <code>python-requests</code> or <code>sqlmap</code> instead of real browsers, and unusually large <code>sc-bytes</code> responses, round out the signals.</p>
<p>An IIS log records HTTP requests to the web server, one line per request, in a text format like W3C. A Windows event log records system, security, and application events on the host, such as logon successes and failures (events 4624 and 4625), service starts, and audit changes, in the structured Windows Event Log store. In an investigation you correlate the two: the IIS log shows the web request, and the event log shows what happened on the host around it.</p>