diff --git a/exercise_0403/go.mod b/exercise_0403/go.mod
new file mode 100644
index 0000000000000000000000000000000000000000..e4b477a80f06085c5e4f5531b4dfa65a026e41e6
--- /dev/null
+++ b/exercise_0403/go.mod
@@ -0,0 +1,3 @@
+module gitlab.reutlingen-university.de/go-exercises/go-starter/exercise_0403
+
+go 1.20
diff --git a/exercise_0403/main.go b/exercise_0403/main.go
new file mode 100644
index 0000000000000000000000000000000000000000..5d9f214ef4001b6aed2bc83f1ff6d9b2628d515e
--- /dev/null
+++ b/exercise_0403/main.go
@@ -0,0 +1,53 @@
+package main
+
+import (
+	"fmt"
+)
+
+type BankAccount struct {
+	balance float32
+	limit   float32
+}
+
+func (ba *BankAccount) Withdraw(amount float32) error {
+
+	if amount > ba.balance+ba.limit {
+		err := BankAccountWithdrawalError{
+			Amount:  amount,
+			Balance: ba.balance,
+			Limit:   ba.limit,
+			Msg:     "amount currently not available",
+		}
+		return err
+	} else {
+		ba.balance -= amount
+		return nil
+	}
+}
+
+type BankAccountWithdrawalError struct {
+	Amount  float32
+	Balance float32
+	Limit   float32
+	Msg     string
+}
+
+func (e BankAccountWithdrawalError) Error() string {
+	return fmt.Sprintf("%s: %f > %f", e.Msg, e.Amount, e.Balance+e.Limit)
+}
+
+func main() {
+	ba := BankAccount{
+		balance: 1000.0,
+		limit:   3000.0,
+	}
+	fmt.Printf("%v\n", ba)
+	if err := ba.Withdraw(5000); err != nil {
+		fmt.Printf("%s\n", err.Error())
+	}
+	fmt.Printf("%v\n", ba)
+	if err := ba.Withdraw(1000); err != nil {
+		fmt.Printf("%s\n", err.Error())
+	}
+	fmt.Printf("%v\n", ba)
+}