diff --git a/ConfigParser.cs b/ConfigParser.cs
index ffae239bccefb6dc56c7eb1d78b6ad6d9d2ceb69..7a49b3b699a9c74a7c4a54548f15885d215ea17f 100644
--- a/ConfigParser.cs
+++ b/ConfigParser.cs
@@ -34,11 +34,13 @@ abstract class ConfigException: Exception
 	{
 		Parser = parser;
 	}
-	public override string ToString()
+	public override string Message
 	{
-		return $"Mistake in config: {ErrorString()}";
+		get => $"Mistake in config: {ErrorStringWithFile()}";
 	}
 	abstract public string ErrorString();
+	public string ErrorStringWithFile()
+		=> Parser.FileName == null ? ErrorString() : $"{Parser.FileName}: {ErrorString()}";
 }
 abstract class ConfigDuplicitException: ConfigException
 {
diff --git a/Module.cs b/Module.cs
index 1234eea67f2c2016f0847a8374230525a022bf77..0957749df7a8fc0c6f24c5148d105bfc26381df3 100644
--- a/Module.cs
+++ b/Module.cs
@@ -421,13 +421,6 @@ text = ERR
 [ModuleName("i3status")]
 class ModuleI3Status: Module
 {
-	class ModuleI3StatusException: ModuleException
-	{
-		public override string ToString()
-		{
-			return $"I3Status don't work correctly.";
-		}
-	}
 	string name;
 	string configuration;
 	Block[] elements;
@@ -480,7 +473,7 @@ class ModuleI3Status: Module
 			string line = process.StandardOutput.ReadLine();
 			if(line == null)
 			{
-				throw new ModuleI3StatusException();
+				throw new PrintAndExit("I3Status don't work correctly.");
 			}
 			Block[] data = (Block[])parser.Parse(line[1..]);
 			if(data.Length != modules.Count)
diff --git a/Program.cs b/Program.cs
index c92a0f5f16382387cedc9979c3117aa6759bda64..4b6f1e5476499abd259cb81d0baba797f6d4e82f 100644
--- a/Program.cs
+++ b/Program.cs
@@ -38,6 +38,19 @@ using Config;
 
 namespace i3csstatus;
 
+class PrintAndExit: Exception
+{
+	public string ToPrint;
+	public int ExitCode;
+	public PrintAndExit(string _ToPrint, int _ExitCode=1)
+	{
+		ToPrint = _ToPrint;
+		ExitCode = _ExitCode;
+	}
+	public override string Message { get => $"Print \"{ToPrint}\" and exit with exit code {ExitCode}"; }
+}
+
+
 static class POSIX
 {
 	[DllImport("libc", SetLastError = true)]
@@ -229,7 +242,14 @@ refresh
 	}
 	protected void parseConfigString(string configString, string? fileName)
 	{
-		parseConfig(new ConfigParser(configString, fileName));
+		try
+		{
+			parseConfig(new ConfigParser(configString, fileName));
+		}
+		catch(ConfigException e) when (e.Parser.FileName == fileName && fileName != null)
+		{
+			throw new PrintAndExit(e.ErrorStringWithFile());
+		}
 	}
 	virtual protected void parseConfig(ConfigParser p)
 	{
@@ -257,6 +277,7 @@ refresh
 			s.Use();
 			s.CheckUnused();
 		}
+		p.MainSection.CheckUnused();
 		p.CheckUnused();
 	}
 	public List<Block> Get()
@@ -589,6 +610,29 @@ class StatusBarI3: RootStatusBar
 class Program
 {
 #pragma warning disable 1998
+	static void LinuxCatch(Action f)
+	{
+		try
+		{
+			f();
+		}
+		catch (PrintAndExit e)
+		{
+			Console.Error.WriteLine(e.ToPrint.Pastel(Color.FromArgb(255,0,0)));
+			Environment.Exit(e.ExitCode);
+		}
+		catch (Exception e)
+		{
+			Console.Error.WriteLine(e.ToString().Pastel(Color.FromArgb(255,0,0)));
+			Console.Error.WriteLine(
+@"
+
+this is not supposed to happen. Please report this bug to
+jirikalvoda+i3csstatus@kam.mff.cuni.cz. Thank you."
+					.Pastel(Color.FromArgb(255,0,0)));
+			Environment.Exit(134);
+		}
+	}
 	static int Main(string[] args)
 	{
 		var configOption = new Option<FileInfo>
@@ -617,7 +661,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.");
 		rootCommand.Add(c_plainText);
 		c_plainText.SetHandler(async (config) =>
 				{
-					(new StatusBarPlainText(config)).Run(Console.Out);
+					LinuxCatch(() => (new StatusBarPlainText(config)).Run(Console.Out));
 				}, configOption);
 
 		var c_terminal = new Command("terminal", "Print status bar with terminal escape secvence.");
@@ -628,7 +672,7 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.");
 		c_terminal.Add(c_terminal_input);
 		c_terminal.SetHandler(async (config, input) =>
 				{
-					(new StatusBarTerminal(config, input)).Run(Console.Out);
+					LinuxCatch(() => (new StatusBarTerminal(config, input)).Run(Console.Out));
 				}, configOption, c_terminal_input);
 
 		var c_i3 = new Command("i3", "Comunicate with i3bar.");
@@ -639,11 +683,10 @@ along with this program.  If not, see <https://www.gnu.org/licenses/>.");
 		c_i3.Add(c_i3_input);
 		c_i3.SetHandler(async (config, input) =>
 				{
-					(new StatusBarI3(config, input)).Run(Console.Out);
+					LinuxCatch(() => (new StatusBarI3(config, input)).Run(Console.Out));
 				}, configOption, c_i3_input);
 
-		rootCommand.Invoke(args);
-		return 0;
+		return rootCommand.Invoke(args);
 	}
 #pragma warning restore 1998
 }