# How to Debug CasaOS Startup Issues and Understand the Initialization Order

> Troubleshoot CasaOS startup problems by understanding its initialization order. Learn how to debug initialization issues and ensure your CasaOS runs smoothly.

- Repository: [IceWhale/CasaOS](https://github.com/IceWhaleTech/CasaOS)
- Tags: how-to-guide
- Published: 2026-06-27

---

**CasaOS initializes through a strict sequence starting with Go's `init()` functions for configuration and service wiring in [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go), followed by `main()` which launches the HTTP server and background goroutines from [`route/init.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/init.go), and you can trace failures by adding `logger.Debug` statements at key points or running the binary manually to see panics on stdout.**

CasaOS is a single Go binary that orchestrates home server functionality through a carefully ordered boot sequence. Understanding how **CasaOS startup issues** originate requires tracing the split between static initialization (global variables and `init()` functions) and dynamic initialization (HTTP server setup and background workers). By examining the source code in the IceWhaleTech/CasaOS repository, you can pinpoint exactly where the boot process fails and instrument the code for detailed debugging.

## CasaOS Initialization Architecture

The boot process divides into two distinct phases. Static initialization runs before `main()` executes, while dynamic initialization happens inside `main()` and continues via background goroutines.

### Static Initialization Phase (init())

In [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go), the `init()` function (lines 58-90) handles critical setup:

1. **CLI flag parsing** via `flag.Parse()`
2. **Configuration loading** via `config.InitSetup` from [`pkg/config/init.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/pkg/config/init.go)
3. **Logger initialization** via `logger.LogInit`
4. **Service construction** via `service.NewService` from [`service/service.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/service.go)
5. **Background worker registration** via `route.InitFunction()`

Any panic during this phase aborts the entire process before `main()` begins.

### Dynamic Initialization Phase (main())

The `main()` function (lines 103-229) completes the startup:

- Creates the HTTP multiplexor
- Registers API routes
- Starts the hardware status cron job
- Launches one-off goroutines (port change monitoring, startup scripts)
- Calls `s.Serve(listener)` to accept connections

## Step-by-Step Initialization Flow

### Configuration Loading (pkg/config/init.go)

The `InitSetup` function reads the INI configuration file:

```go
func InitSetup(config string, sample string) {
    ConfigFilePath = CasaOSConfigFilePath
    if len(config) > 0 {
        ConfigFilePath = config
    }
    // create default config if missing
    Cfg, err = ini.Load(ConfigFilePath)   // failure here stops start-up
    mapTo("app", AppInfo)
    mapTo("server", ServerInfo)
    // ...
}

```

If [`/etc/casaos/casaos.conf`](https://github.com/IceWhaleTech/CasaOS/blob/main//etc/casaos/casaos.conf) is corrupted or unreadable, the program panics at line 73.

### Service Construction (service/service.go)

The `NewService` constructor wires together the `Repository` containing:

- **CasaService** (`NewCasaService()`) - UI/portal handling
- **SystemService** (`NewSystemService()`) - hardware queries (MAC, thermal zones)
- **StorageService** (`NewStorageService()`) - mount handling
- **NotifyService** (`NewNotifyService(db)`) - event notifications
- **Gateway** (`external.NewManagementService(RuntimePath)`) - reverse-proxy routes

Each constructor may access the filesystem or external daemons, surfacing failures as initialization panics.

### Background Workers (route/init.go)

`route.InitFunction()` spawns two critical goroutines:

- **InitInfo()** - Immediately writes [`baseinfo.conf`](https://github.com/IceWhaleTech/CasaOS/blob/main/baseinfo.conf) with MAC hash and OS version
- **InitNetworkMount()** - Waits 10 seconds, then mounts Samba connections and storage devices

These rely on the global `service.MyService` instance, executing concurrently while the HTTP server runs.

## Debugging Techniques for Startup Failures

### Enable Verbose Logging

Set `config.AppInfo.LogSaveName` to include `debug` or modify `log.Init` to use `zap.NewDevelopment()`. Logs write to `$RUNTIME_PATH/logs` (default `/var/lib/casaos/log`).

### Add Strategic Debug Statements

Insert `logger.Debug` calls at key instrumentation points:

```go
func init() {
    flag.Parse()
    if *versionFlag {
        fmt.Println("v" + common.VERSION)
        return
    }

    logger.LogInit(config.AppInfo.LogPath, config.AppInfo.LogSaveName, config.AppInfo.LogFileExt)
    logger.Debug("starting InitSetup", zap.String("configFlag", *configFlag))
    config.InitSetup(*configFlag, _confSample)
    // ...
}

```

Place similar statements in `InitInfo()` and `InitNetworkMount()` to verify execution order.

### Run the Binary Manually

Bypass systemd to see panics directly on stdout:

```bash
sudo -E /usr/bin/casaos -c /etc/casaos/casaos.conf

```

The `-E` flag preserves environment variables required by the binary.

### Systemd Status Inspection

Check service status for `daemon.SdNotifyReady` confirmation:

```bash
systemctl status casaos

```

### File System Tracing

Use `strace` to identify file access failures:

```bash
sudo strace -f -e trace=file -p <pid>

```

## Common Failure Points and Solutions

| Symptom | Likely Cause | Solution |
|---------|--------------|----------|
| Panic in `InitSetup` with "invalid character" error | Corrupted [`/etc/casaos/casaos.conf`](https://github.com/IceWhaleTech/CasaOS/blob/main//etc/casaos/casaos.conf) | Delete the file and let CasaOS regenerate it |
| Panic in `NewService` at `external.NewManagementService` | Missing `/run/casaos` runtime directory | Verify `$RUNTIME_PATH` exists and is writable |
| `InitNetworkMount` hangs with mount errors | Unreachable Samba shares | Temporarily comment out the `InitNetworkMount` call in [`route/init.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/init.go) line 34 |
| HTTP server fails to listen | Port already bound | Check systemd journal for `listen tcp` errors or modify `config.ServerInfo.HttpPort` |

## Code Examples for Instrumentation

### Verifying Background Task Execution

Add timeline markers to track concurrent initialization:

```go
func InitInfo() {
    logger.Debug("InitInfo started")
    // existing initialization code
    logger.Debug("InitInfo completed", zap.Any("baseinfo", mb))
}

func InitNetworkMount() {
    logger.Debug("InitNetworkMount waking after 10s")
    // existing mount code
    logger.Debug("InitNetworkMount finished")
}

```

These entries appear in the log file, revealing the exact interleaving of startup events.

### Checking Configuration Load

Verify config file handling before the INI parser executes:

```go
func InitSetup(config string, sample string) {
    logger.Debug("checking config file", zap.String("path", ConfigFilePath))
    // ... existing code
    Cfg, err = ini.Load(ConfigFilePath)
    if err != nil {
        logger.Error("failed to load config", zap.Error(err))
        panic(err)
    }
}

```

## Summary

- CasaOS boots as a single Go binary with initialization split between `init()` (static) and `main()` (dynamic)
- The `init()` function in [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go) (lines 58-90) parses flags, loads configuration via [`pkg/config/init.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/pkg/config/init.go), initializes services via [`service/service.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/service.go), and registers background workers
- `main()` (lines 103-229) launches the HTTP server, cron jobs, and additional goroutines
- Background initialization in [`route/init.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/init.go) includes `InitInfo()` (immediate) and `InitNetworkMount()` (delayed 10 seconds)
- Debug startup issues by adding `logger.Debug` statements, running the binary manually with `sudo -E`, and checking `/var/lib/casaos/log`
- Common failures include corrupted config files, missing runtime directories, and network mount timeouts

## Frequently Asked Questions

### Why does CasaOS panic before logging any output?

If the panic occurs in `init()` before `logger.LogInit` completes (around line 68 of [`main/main.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/main/main.go)), no log file exists yet. Run the binary manually with `sudo /usr/bin/casaos` to see the stack trace on stdout, or add `fmt.Println` statements temporarily to identify which initialization step fails.

### How can I disable the automatic network mounting during startup?

Comment out the `InitNetworkMount()` goroutine launch in [`route/init.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/init.go) (line 34). This prevents the 10-second delay and potential hang when Samba shares are unreachable, allowing the HTTP server to start immediately while isolating storage connectivity issues.

### Where does CasaOS store its startup logs?

Logs write to `$RUNTIME_PATH/logs` (default `/var/lib/casaos/log`) as defined by `config.AppInfo.LogPath`. If the logger fails to initialize, check `stderr` via `systemctl status casaos` or run the binary manually to see unbuffered output.

### What is the correct initialization order for CasaOS services?

According to the IceWhaleTech/CasaOS source code, the order is: **Configuration loading** (`InitSetup`) → **Logger initialization** → **Service construction** (`NewService` creating Casa, System, Storage, Notify, and Gateway services) → **Route initialization** (`InitFunction` spawning `InitInfo` and `InitNetworkMount`) → **HTTP server startup** (`s.Serve`). Any failure in this sequence aborts subsequent steps.