Network Sketcher is an open-source toolkit from Cisco for designing,
documenting, and rendering enterprise networks layer-by-layer (L1 / L2 / L3)
straight out of an Excel master file. You drive every change with a
five-verb command-line — add, delete, rename, show, export — and
get back PowerPoint, SVG, Visio (.vsdx-friendly) and draw.io artifacts
that match what your network actually looks like.
The project ships in two editions that share an engine:
- Network Sketcher Online — a self-hosted Flask web app (HTTPS on
port
5443by default) that you upload a master file to and click through. - Network Sketcher Offline — a Tkinter desktop GUI plus the same CLI, bundled for direct use on a workstation.
This guide covers everyday usage for both editions. If you maintain the service for a team, deploy it on a shared host, or want to understand the engine internals, see the Administrator & Developer Guide.
Note
Network Sketcher does not ingest live device telemetry, scrape running configs, or talk to controllers. It is a deterministic renderer of the data you put in the master file. Drawings are reproducible byte-for-byte when the master file is unchanged.
1. Quick Start
The fastest path to your first diagram is the Online edition: it
auto-generates a self-signed TLS certificate, opens an HTTPS endpoint at
https://localhost:5443, and lets you drag-and-drop a master file in your
browser. No CLI knowledge is required to render.
# From the cloned repository root
python start_ns_online.py
========================================================
Network Sketcher Online — Start
========================================================
Server started (PID: 28144)
PID file: network-sketcher_online/ns_online.pid
========================================================
Open https://localhost:5443/ in your browser. On the first page:
- Drop your
[MASTER]<name>.xlsxmaster file in the upload zone (or click Create New Master File for an empty template). - Wait for the Available Outputs list to populate. Each item has its own Generate button, or click Generate Selected to build everything queued.
- Preview renders inline (PowerPoint and Excel preview without Office installed). Download ships the file.
Tip
Don't have Excel installed and just want to see what the tool produces? Click Create New Master File, then Generate Selected with the default outputs checked — you'll get an L1, L2, and L3 sample diagram from the built-in
[MASTER]no_data.xlsxtemplate in under a minute.
If you'd rather drive everything from a terminal, the same engine is available as a CLI:
cd network-sketcher_offline
python ns_cli.py export l1_diagram \
--master "[MASTER]my_design.xlsx" \
--type all_areas_tag
--- L1 Diagram exported successfully ---
[L1_DIAGRAM]AllAreasTag_my_design.pptx
What you'll need
- [x] Python 3.9 or newer (3.11+ recommended)
- [x]
openpyxl,pandas,pyarrow,python-pptx,networkx,numpy - [x] Online edition only:
flask,cryptography(for self-signed certs) - [x] Offline edition only: a working Tk install (
python-tk/tkinterdnd2) for the desktop GUI; the CLI also runs without Tk - [x] About 200 MB of disk space for source plus dependencies
Important
Master files must start with the literal prefix
[MASTER]and end in.xlsxor.nsm. The web upload route rejects everything else withFilename must start with [MASTER].
What you'll see in your first 60 seconds
| You did | Network Sketcher produced |
|---|---|
Uploaded [MASTER]demo.xlsx |
One L1 All-Areas PowerPoint, one per-area L1 diagram per area in the master, an L2 diagram per L2 broadcast domain, one L3 All-Areas diagram, and a [DEVICE]demo.xlsx summary workbook. |
| Clicked Generate on a single output | A .pptx (default) or .svg (if you toggle the format), saved to the per-job upload directory and offered for download. |
Pasted CLI commands like add device R5 area=DC1 |
A new versioned master ([MASTER]demo_2.xlsx) reflecting the change — your original is preserved for rollback. |
Where to go next
- First-time tour: keep reading Section 4 (Core Usage).
- Already drawing networks? skip to Section 5 (Common Tasks) for recipes such as multi-area pods and AI-context generation.
- Hosting it for your team? start with the Administrator & Developer Guide.
2. Installation
Network Sketcher is distributed as source from GitHub. There are no PyPI wheels, no Docker images shipped by Cisco, and no installer — you clone, you install dependencies, you run. The two editions live side-by-side in the same repository.
2.1 Choose an edition
| Capability | Offline (network_sketcher.py) |
Online (ns_web_start.py) |
|---|---|---|
| Tkinter desktop GUI | Yes | No (headless / browser only) |
| Browser UI | No | Yes (HTTPS, port 5443 by default) |
CLI (add / delete / rename / show / export) |
Yes (ns_cli.py) |
Yes (in-process via ns_engine) |
External-system import (*.yaml, *.svg, *.csv) |
Yes (drag-and-drop pane) | No (CLI/manual) |
| Multi-user | No (single-process desktop) | Yes (per-job_id upload dirs) |
| Parallel diagram generation | Single-threaded | Up to parallel_limit workers (default 6) |
| Self-signed TLS auto-generation | N/A | Yes (`Certs/server.crt |
| Heartbeat session cleanup | N/A | Yes (5-minute idle expiry by default) |
Tip
If you only need to render diagrams locally, the Offline CLI is the simplest path — no Flask, no certs, no browser. The web UI is the right choice when more than one person needs to use the tool at once or when you want the polished drag-and-drop experience.
2.2 Get the source
git clone https://github.com/cisco-open/network-sketcher.git
cd network-sketcher
2.3 Install dependencies
The two editions ship separate requirements files
(network-sketcher_offline/requirements_offline.txt and
network-sketcher_online/requirements_online.txt). Install whichever
edition(s) you plan to run:
Offline edition
cd network-sketcher_offline
python -m pip install -r requirements_offline.txt
Online edition
cd network-sketcher_online
python -m pip install -r requirements_online.txt
Both
python -m pip install -r network-sketcher_offline/requirements_offline.txt
python -m pip install -r network-sketcher_online/requirements_online.txt
Important
The Offline GUI imports
tkinterandtkinterdnd2. On Linux distributions that don't ship Tk by default, install your distro'spython3-tkpackage first (e.g.sudo apt install python3-tk). The Online edition is headless — it stubs outtkinterand runs without any display server, so it works fine in containers and on locked-down servers.
2.4 Verify
Offline CLI
cd network-sketcher_offline
python ns_cli.py
[ERROR] Master file must be selected --master <filepath>.
Seeing the --master error means the CLI dispatcher is wired up.
Offline GUI
cd network-sketcher_offline
python network_sketcher.py
A window titled Network Sketcher Offline ver 3.0.1h should open with
a Main Panel tab.
Online
python start_ns_online.py
Then open https://localhost:5443/. You will see a TLS warning the
first time because the cert is self-signed — see Troubleshooting.
2.5 Stopping the Online server
stop_ns_online.py finds every running ns_web_start.py process (even
ones launched outside the start script) and terminates them, removing the
PID file on success.
python stop_ns_online.py
========================================================
Network Sketcher Online — Stop
========================================================
Found 1 running server process(es): [28144]
Stopping PID 28144...
Stopped 1 process(es).
========================================================
Warning
stop_ns_online.pysendsSIGTERM(POSIX) ortaskkill /F /T(Windows). Any in-flight diagram generation is aborted immediately. Wait for the All server processes stopped line before restarting —start_ns_online.pyalready does this for you when you use it to restart, but a manualpython ns_web_start.pywill not.
2.6 First-launch artifacts (Online)
On first start, the server creates these directories and files. They're
all under network-sketcher_online/:
| Path | Purpose | First-run behavior |
|---|---|---|
Certs/server.crt, Certs/server.key |
TLS certificate plus private key | Auto-generated 4096-bit RSA self-signed cert valid for 10 years (ssl_cert_validity_days: 3650) if either is missing |
logs/access_YYYYMMDD.log |
Per-day access log (one file per local date) | Created on first request; old files older than access_log_retention_days (default 90) are deleted automatically |
logs/server.log |
stdout / stderr from the Flask app | Created by start_ns_online.py |
uploads/<uuid>/ |
Per-job working directory | Created on each /upload POST; cleared after the heartbeat expires |
ns_online.pid |
PID of the running server | Used by stop_ns_online.py |
3. Configuration
The Online edition reads network-sketcher_online/ns_web_config.json once
at startup. Every key is documented inline in that file. The Offline CLI
takes no config file — all behavior is controlled by command-line flags.
3.1 The ns_web_config.json keys you'll touch most
| Key | Default | What it controls |
|---|---|---|
host |
localhost |
Bind address. Use 0.0.0.0 to expose to the LAN, or pin to a specific NIC IP |
port |
5443 |
HTTPS listen port |
fqdn |
null |
If non-null, used as the certificate Common Name instead of host |
max_file_size_mb |
50 |
Upload size cap; rejected uploads return HTTP 413 |
subprocess_timeout |
14400 (4 hours) |
Wall-clock cap on each diagram subprocess; null for no limit |
heartbeat_timeout |
300 (5 min) |
Idle window after which a session's uploads/<job_id>/ is wiped |
cleanup_interval |
60 |
Seconds between idle-sweep runs |
parallel_limit |
6 |
Max diagrams generated concurrently per /svg_grid_stream call |
log_level |
INFO |
One of DEBUG, INFO, WARNING, ERROR |
access_log_retention_days |
90 |
How many access_*.log files to keep |
ai_context_button_label |
Copy & Open LLM |
The button text on the AI Context panel |
ai_context_button_url |
https://claude.ai |
Where the Copy & Open LLM button opens |
The full reference, including TLS fields (ssl_cert_path, ssl_key_path,
ssl_min_version, ssl_max_version, ssl_ciphers,
ssl_cert_validity_days, ssl_key_size) and the AI-context show-command
list (ai_context_show_commands), lives in the Administrator & Developer
Guide.
3.2 Environment variables
The Online server sets NS_WEB_SERVER=1 for every child process it
spawns; engine modules check this to suppress GUI fall-backs. You don't
normally set it yourself unless you're embedding the engine.
| Variable | Read in | Effect |
|---|---|---|
NS_WEB_SERVER |
nsm_l2_diagram_create.py and other engine modules |
When set to any value, engine code follows the headless / server code path (no Tk, no print spam) |
NS_DEBUG_L3 |
nsm_l3_diagram_create.py |
Set to 1 to dump verbose L3-layout diagnostics to stdout. Default 0. Helpful when investigating L3 layout bugs (see Troubleshooting issue #59) |
Note
Master file paths and CLI subcommand names are not environment-driven. Every input is a flag on
ns_cli.pyor a JSON config key. This makes Network Sketcher trivially reproducible across machines.
3.3 Editing config safely
# 1. Stop the server cleanly
python stop_ns_online.py
# 2. Edit the JSON
${EDITOR:-vi} network-sketcher_online/ns_web_config.json
# 3. Restart
python start_ns_online.py
Warning
Comments are not supported in
ns_web_config.json(it's strict JSON, not JSONC). Each top-level field is{"value": ..., "description": "..."}; the loader strips the description and only thevalueis read. Any field whose name starts with an underscore (e.g._description) is ignored.
4. Core Usage
Network Sketcher is built around one pivotal artifact — the master file — and three production paths that read it.
4.1 The master file
Every workflow starts here. The master file is an Excel workbook (.xlsx)
with three well-known worksheets:
Master_Data— single source of truth for areas, devices, L1 wires, positions, styles, and device attributes. Sections are tagged with<<ROOT_FOLDER>>,<<POSITION_FOLDER>>,<<STYLE_FOLDER>>,<<POSITION_SHAPE>>,<<STYLE_SHAPE>>,<<POSITION_LINE>>,<<POSITION_TAG>>,<<ATTRIBUTE>>, and<<END_MARK>>.Master_Data_L2— L2 broadcast-domain memberships (<<L2_TABLE>>).Master_Data_L3— L3 interface and IP-address assignments (<<L3_TABLE>>).
The Online server also accepts a compact binary form, .nsm, which is
just a ZIP of Parquet sections (ROOT_FOLDER.parquet,
POSITION_FOLDER.parquet, STYLE_FOLDER.parquet, POSITION_SHAPE.parquet,
STYLE_SHAPE.parquet, POSITION_LINE.parquet, POSITION_TAG.parquet,
ATTRIBUTE.parquet, L2_TABLE.parquet, L3_TABLE.parquet,
END_MARK.parquet). Uploads of .xlsx are converted to .nsm immediately
on receipt for faster downstream operations; the original is kept.
Tip
Don't have a master file to start from? Either click Create New Master File in the web UI, or run
python ns_cli.py export master_file_nodata --master /tmp/dummy.xlsxand grab the resulting[MASTER]no_data.xlsx.
4.2 The five CLI verbs
ns_cli.py {add|delete|rename|show|export} <object> [--<flag> <value> ...] --master <path>
The five top-level verbs and their object surfaces:
| Verb | Objects |
|---|---|
show |
area, area_device, area_location, area_waypoint, attribute, device, device_interface, device_location, l1_interface, l1_link, l2_broadcast_domain, l2_interface, l3_broadcast_domain, l3_interface, waypoint, waypoint_interface, waypoint_location |
add |
area_location, device, device_location, ip_address, ip_address_bulk, l1_link, l1_link_bulk, l2_segment, l2_segment_bulk, portchannel, portchannel_bulk, virtual_port, virtual_port_bulk, vport_l1if_direct_binding, vport_l2_direct_binding, waypoint |
delete |
area, device, ip_address, l1_link, l2_segment, portchannel, virtual_port, vport_l1if_direct_binding, vport_l2_direct_binding, waypoint |
rename |
area, attribute_bulk, device, l3_instance, port, port_info_bulk |
export |
ai_context_file, master_file_backup, master_file_nodata, device_file, l1_diagram, l2_diagram, l3_diagram |
Every verb requires --master <path> pointing at a [MASTER]*.xlsx (or
.nsm) file. The export verb adds object-specific flags such as
--type, --area, --attribute, and --format.
Note
The
--masterflag is positional in spirit but technically a named flag — it can appear anywhere on the line. The CLI rejects any command that doesn't include it with[ERROR] Master file must be selected --master <filepath>..
4.3 The export flag matrix
These are the flags the engine actually inspects, by output type:
| Export | Required flags | Optional flags | Default behavior |
|---|---|---|---|
l1_diagram |
--master |
--type {all_areas, all_areas_tag, per_area, per_area_tag}, --attribute <title>, --format {pptx, svg} |
--type all_areas_tag --format pptx |
l2_diagram |
--master, --area <name> |
--format {pptx, svg} |
--format pptx |
l3_diagram |
--master |
--type {all_areas, per_area}, --attribute <title>, --format {pptx, svg} |
--type all_areas --format pptx |
device_file |
--master |
— | Always emits [DEVICE]<basename>.xlsx |
ai_context_file |
--master, --accept-security-risk |
— | Emits [AI_Context]<basename>.txt |
master_file_nodata |
--master |
— | Emits [MASTER]no_data.xlsx next to the input |
master_file_backup |
--master |
— | Emits a timestamped backup |
Important
export ai_context_filewill refuse to run unattended unless you pass--accept-security-risk. The interactive prompt requires a literal uppercaseYES. This is intentional: the AI Context bundles your entire network plan (areas, devices, IPs, segments, VPN targets) into a single text file meant to be pasted into a hosted LLM — see Section 5.4.
4.4 The Online HTTP surface
When the web UI does anything, it's calling these routes. They're useful to know if you're scripting against the server.
| Method | Route | Purpose |
|---|---|---|
GET |
/ |
Renders the single-page UI |
POST |
/upload |
Uploads a master file; returns {job_id, filename} |
POST |
/create_empty_master |
Streams down a fresh [MASTER]no_data.xlsx |
POST |
/heartbeat/<job_id> |
Resets the idle-eviction clock for a session |
GET |
/restore/<job_id> |
Rehydrates a session (master, areas, device count, generated files) |
POST |
/generate_step/<job_id>/<step> |
Generates a single output type (e.g. l1_diagram, l2_diagram, l3_diagram, device_file, ai_context_file) |
POST |
/run_commands/<job_id> |
Executes a batch of add/delete/rename/show commands and creates a versioned master |
GET |
/svg_grid_stream/<job_id> |
Server-Sent-Events stream of all SVGs in parallel |
GET |
/files/<job_id> |
JSON list of generated artifacts |
GET |
/download/<job_id>/<filename> |
Raw download |
GET |
/download_visio/<job_id>/<filename> |
SVG converted to a Visio-friendly form |
GET |
/download_drawio/<job_id>/<filename> |
SVG converted to draw.io XML |
GET |
/download_all/<job_id> |
ZIP of every artifact for the session |
GET |
/preview/<job_id>/<filename> |
In-browser preview (SVG, PowerPoint, Excel) |
<job_id> is always a UUID4. The server validates it strictly with
re.match(r'^[a-f0-9\-]{36}$', job_id); anything else returns 400.
5. Common Tasks
5.1 Build an L1 diagram for every area in one go
cd network-sketcher_offline
python ns_cli.py export l1_diagram \
--master "[MASTER]campus.xlsx" \
--type all_areas_tag \
--format pptx
--- L1 Diagram exported successfully ---
[L1_DIAGRAM]AllAreasTag_campus.pptx
--type value |
Output |
|---|---|
all_areas |
One diagram of the entire network, without interface name tags |
all_areas_tag |
One diagram of the entire network, with interface name tags |
per_area |
One diagram per area, without tags |
per_area_tag |
One diagram per area, with tags |
The web UI calls the same engine with --type all_areas_tag for the main
preview pane and --type per_area_tag for the per-area thumbnails.
5.2 Render an L2 broadcast domain to SVG
L2 diagrams are area-scoped — there's no "all L2" view because broadcast domains rarely span an entire backbone.
python ns_cli.py export l2_diagram \
--master "[MASTER]campus.xlsx" \
--area "DC1-LEAF" \
--format svg
--- L2 Diagram exported successfully ---
[L2_DIAGRAM]DC1-LEAF_campus.svg
Note
If you pass an area name that doesn't exist in the master file's
Master_Data_L2sheet, the command emits[WARNING] No L2 segments found in area '<name>'and exits without writing a file.
5.3 Color devices by an attribute (e.g. role / vendor)
L1 and L3 diagrams accept --attribute <title>, which paints each device
according to the column you name in the master file's Attribute sheet.
python ns_cli.py export l1_diagram \
--master "[MASTER]campus.xlsx" \
--type all_areas_tag \
--attribute "Role"
In the web UI, the same control is the Attribute dropdown on the main panel. Switching it forces the SVG grid to regenerate; the previous attribute value is cached so flipping back-and-forth is free.
5.4 Bulk-update the master with LLM-generated commands
The fastest way to mutate a large master file is to ask an LLM to produce
the right add / delete / rename / show commands and paste them
into the Update Master panel of the web UI (or feed them line-by-line
through ns_cli.py).
- Click Generate on the AI Context File card. The server runs all
showcommands in parallel and writes[AI_Context]<basename>.txt. - Type a request in the LLM Prompt field (e.g. "Add a new aggregation switch AGG-3 to area DC2-AGG with two L1 links to AGG-1 and AGG-2").
- Click Copy & Open LLM — the AI Context plus your prompt is copied to the clipboard and Claude (or your configured LLM) opens in a new tab.
- Paste the LLM-generated command list into the CLI Commands box and click Run.
The server dispatches them with --skip_sync on every step except the
last of a syncable run, then performs one consolidated L2/L3 sync. A new
versioned master ([MASTER]<basename>_<n>.xlsx) is written so your
original is never overwritten.
Caution
The AI Context file contains your entire network plan in plain text: device names, IP plans, VLANs, VPN targets, area hierarchy. Treat it like any other configuration export. The Offline CLI requires
--accept-security-riskto skip the interactiveYESprompt — see Section 7 of the Administrator & Developer Guide for the recommended handling guidance.
5.5 Export a Visio- or draw.io-friendly diagram
The web UI exposes two derived downloads beside every SVG output:
- Download Visio — calls
/download_visio/<job_id>/<filename>, which inlines CSS classes, drops SVG2-only attributes (dominant-baseline,auto-start-reversemarkers), strips outer-frame<rect>elements, and forcesfill="white"on transparent rects so Visio doesn't fill them black. - Download draw.io — calls
/download_drawio/<job_id>/<filename>, which parses the Network Sketcher SVG and emits a fully-mappedmxGraphModelwithmxCellnodes for rects, edges for lines, and merged labels for text inside rects. Open the.drawiofile in draw.io or diagrams.net and edit it as a normal diagram.
Both transforms run on the cached SVG bytes — no engine re-execution is required, so they're fast.
5.6 Generate a device summary workbook
python ns_cli.py export device_file --master "[MASTER]campus.xlsx"
--- Device file created successfully ---
The output, [DEVICE]campus.xlsx, contains four normalized sheets — L1
table, L2 table, L3 table, and Attribute table — derived from the master
data. This is the workbook to hand to a network engineer who wants
"the table of every interface."
5.7 Restore a browser session after refresh / disconnect
The web UI persists every session in
network-sketcher_online/uploads/<job_id>/ for up to heartbeat_timeout
seconds (5 minutes by default) of idleness. If you reload the page, the
front-end calls /restore/<job_id> with the UUID it saved in
localStorage; you get back the master filename, area list, device
count, link count, and the inventory of generated files.
Tip
If you closed the tab more than five minutes ago, the upload directory has been wiped. Re-upload your master file — Network Sketcher is deterministic, so identical input gives identical output.
5.8 Stand up a multi-area pod from scratch
This is the recipe for a typical leaf-spine fabric in a brand-new master file.
- Create an empty master.
POST /create_empty_master(or click Create New Master File) downloads[MASTER]no_data.xlsx. - Add areas. Use the CLI Commands panel:
add area_location DC1-SPINE 0 0 add area_location DC1-LEAF 0 1 add area_location DC2-SPINE 1 0 add area_location DC2-LEAF 1 1 - Add devices with explicit area assignment:
add device SPINE-1 area=DC1-SPINE add device SPINE-2 area=DC1-SPINE add device LEAF-1 area=DC1-LEAF add device LEAF-2 area=DC1-LEAF - Wire L1 links (use the bulk form for many at once):
add l1_link_bulk [["SPINE-1","Eth1/1","LEAF-1","Eth1/49"],["SPINE-1","Eth1/2","LEAF-2","Eth1/49"],["SPINE-2","Eth1/1","LEAF-1","Eth1/50"],["SPINE-2","Eth1/2","LEAF-2","Eth1/50"]] - Render. Click Generate Selected with L1, L2, and L3 outputs all checked.
6. Troubleshooting
A diagnostic decision tree:
diagram won't render?
├── output file is missing entirely?
│ └── check stdout/stderr for [ERROR] / [WARNING] markers (see below)
├── output file exists but is empty / blank?
│ ├── L2 diagram? → confirm the area name with `show area`
│ └── L3 diagram? → set NS_DEBUG_L3=1 and re-run for verbose layout output
├── browser shows TLS warning?
│ └── that's expected on first connect — see issue below
└── server says "stuck"?
└── check `network-sketcher_online/logs/server.log` for traceback
Error: [ERROR] Master file must be selected --master <filepath>.
Cause: the CLI was invoked without --master <path>.
Solution: always pass --master. Even show commands require it.
python ns_cli.py show area --master "[MASTER]campus.xlsx"
Prevention: wrap your most-used invocations in shell aliases that
already include --master "$NS_MASTER".
Error: Filename must start with [MASTER]
Cause: the web upload validator rejected a file that didn't begin
with the literal prefix [MASTER].
Solution: rename the file. Network Sketcher uses the prefix to
disambiguate generated outputs ([L1_DIAGRAM], [L2_DIAGRAM],
[L3_DIAGRAM], [DEVICE], [AI_Context]) from inputs.
Prevention: the Create New Master File button always names files correctly.
Error: Sheet '<name>' not found in the workbook.
Cause: the master file is missing one of the well-known sheets
(Master_Data, Master_Data_L2, or Master_Data_L3). Most often this
happens after an external edit in Excel where someone renamed a sheet by
hand.
Solution: open the workbook in Excel, restore the original sheet
name, and re-upload. The full list of expected sheet plus section pairs
is in nsm_io.py (see Section 8 of the Administrator & Developer
Guide).
Prevention: treat the master file as machine-managed. Make changes
through CLI verbs (add / rename / delete) instead of direct Excel
edits.
Error: Single-core fallback failed: Worker context not initialized
Cause: the L2 diagram generator's multiprocessing pool failed to
start and the single-core retry path also failed to bootstrap. This is
the diagnostic from nsm_l2_diagram_create.py:507
(ns_l2_diagram_create.py:503 in the Offline edition).
Solution: restart the Online server (python stop_ns_online.py && python start_ns_online.py) so a fresh pool is created. If the problem
persists, set parallel_limit to 1 in ns_web_config.json to force
the single-core path and re-test.
Prevention: keep at least 2 GB of free RAM per concurrent diagram on busy servers. Out-of-memory kills are the most common cause.
Error: [ERROR] 処理がタイムアウトしました (600秒超過)。
Cause: a diagram subprocess exceeded subprocess_timeout. The full
message advises reducing the dataset ("for L3 All Areas, reduce the
number of areas or devices, or confirm with Per Area").
Solution: for L3, switch from --type all_areas to --type per_area to render area-by-area. For all diagram types, raise
subprocess_timeout in ns_web_config.json (or set it to null for no
limit) on a host with enough RAM.
Prevention: profile your largest expected master file once and pin
subprocess_timeout accordingly.
Error: All random numbers (9000-9999) have been exhausted.
Cause: the temporary-name generator in
ns_option_convert_to_master.py creates short numeric suffixes between
9000 and 9999. If you import 1000+ external diagrams without
restarting the GUI, every slot is taken.
Solution: restart the Offline GUI (this resets the generator) or close and reopen the file dialog.
Prevention: import in batches of a few hundred and restart between them.
Issue: Browser shows "Your connection is not private" on first launch
Cause: Network Sketcher Online auto-generates a self-signed TLS
certificate (Certs/server.crt) on first start. Browsers correctly flag
it because no public CA signed it.
Solution: click Advanced → Proceed to localhost (unsafe). If
you're exposing the server to a LAN, replace Certs/server.crt and
Certs/server.key with a cert from your internal CA and restart.
Prevention: see "Production TLS" in the Administrator & Developer Guide.
Issue: "L3 Configuration Diagram Bug Report" — known issue #59
Status: open as of 2026-04-28. Layout glitches in some edge-case L3
topologies. Set NS_DEBUG_L3=1 and capture stdout when reporting; that
output gives the maintainers the layout traces they need.
Issue: "L2 diagram/Per Area causes AttributionError" — fixed in #56
Status: closed. Make sure you're on the latest main (commit
ae4fafb or newer).
Issue: "Adding an L1 wire on a device may delete L2 information on other wires" — fixed in #55
Status: closed. The fix lives in nsm_sync_between_layers.py. If
you hit this on an older checkout, upgrade.
Issue: "File path concatenation error causes 'No such file or directory'" — fixed in #54
Status: closed. Was Windows path-separator handling.
Issue: add area_location doesn't update the wire location — fixed in #58
Status: closed. After adding a new area, an add l1_link against
devices in that area now updates wire coordinates correctly.
Warning
If a master file becomes unparseable (
openpyxlraises), the engine has no auto-repair. Always keep the timestamped backups in place — the CLI'sexport master_file_backupand the web upload's auto-versioning are your safety net. Do not delete[MASTER]<name>_<n>.xlsxfiles until you're confident the latest version is good.
7. FAQ
Q: What's the difference between .xlsx and .nsm?
.xlsx is the human-editable Excel form; .nsm is a compact ZIP of
Parquet form the engine uses internally for speed. The web upload route
accepts either and converts .xlsx to .nsm immediately (xlsx_to_nsm
in nsm_io.py). For day-to-day use, stick with .xlsx — it's the
source of truth.
Q: Can I run Network Sketcher headlessly in a container?
Yes — the Online edition is headless by design. Its
ns_engine/nsm_adapter.py injects no-op stubs for tkinter,
tkinter.ttk, tkinter.filedialog, and tkinter.messagebox, so no
display server is needed. You only need a Python 3.9+ runtime and the
requirements_online.txt dependencies.
Q: Can I integrate with NetBox / CML / Visio / draw.io?
Yes for ingestion: the Offline GUI's External Systems tab accepts CML YAML, Visio SVG, draw.io SVG, and NetBox CSV exports and converts them into a master file. For round-tripping out, every SVG output has a one-click Visio and draw.io transform (see Section 5.5).
Q: Why did the web UI create [MASTER]campus_2.xlsx after I ran some
commands?
Any batch of CLI commands containing add, delete, or rename is
treated as a mutation and produces a new versioned master. Your original
is untouched. The "active master" pointer is moved to the new file
automatically; you can revert by editing .active_master in the upload
directory.
Q: How do I prevent the AI Context export prompt from blocking my script?
Pass --accept-security-risk on the CLI:
python ns_cli.py export ai_context_file \
--master "[MASTER]campus.xlsx" \
--accept-security-risk
This skips the interactive YES prompt. Only do this in environments
where you've separately addressed where the resulting file goes — the
AI Context bundles your entire network plan in plain text.
Q: Where do generated files go?
| Edition | Path |
|---|---|
| Offline CLI | Same directory as the input [MASTER]*.xlsx |
| Offline GUI | Same directory as the input file |
| Online | network-sketcher_online/uploads/<job_id>/, downloadable via the web UI; cleared after heartbeat_timeout seconds of inactivity |
Q: How do I increase the upload size limit beyond 50 MB?
Edit network-sketcher_online/ns_web_config.json and bump
max_file_size_mb. Restart the server.
Q: Does Network Sketcher support multiple users at the same time?
The Online server isolates every upload by job_id (UUID4), so
multiple users can use the same instance concurrently. The Offline GUI
is single-user per process; run separate copies for separate users.
Q: Where is logging?
| Log | Path | Format |
|---|---|---|
| Access log | network-sketcher_online/logs/access_YYYYMMDD.log |
One file per local date, retained access_log_retention_days days |
| Server log | network-sketcher_online/logs/server.log |
Application stdout/stderr |
| Offline CLI | stdout only | Use shell redirection for persistence |
Q: How do I report a bug?
Open an issue at
github.com/cisco-open/network-sketcher/issues.
Include the master file (or a minimized one that reproduces), the exact
CLI command or web-UI clicks, and the captured output (server.log for
the Online edition).
Q: Is there a license fee?
No. Network Sketcher is licensed under Apache 2.0. Cisco Systems holds the copyright; community contributions are welcome under the Cisco Open project's CLA.