Decode FEN string into separate variables for the 6 categories
Code should be correct, maintainable, robust, reasonably efficient, and, most importantly, readable.

To be certain that the code is correct, carefully read the specification and related documents.
Forsyth–Edwards Notation
PGN-SPEC
Portable Game Notation
Algebraic notation (chess)
Chess
For a code review, compare the specification and the code implementing it side-by-side.

In chess, there are pieces placed on squares which are organized into ranks and files to form a board. There doesn't appear to be any references to these basic concepts, apart from board, in decodeFen. Therefore, comparison of code to specification is difficult.
&quot;PGN is &quot;Portable Game Notation&quot;, a standard designed for the representation of chess game data using ASCII text files. PGN data is represented using a subset of the eight bit ISO 8859/1 (Latin 1) character set.&quot; Therefore,
var board [8][8]int8

is incorrect. Characters are not type int8 (8-bit signed integers). Characters are type byte (8 bits).
var board [8][8]byte

The code
for _, char := range row { ... }

expects a UTF-8 encoded string. UTF-8 encoding is not the same as ISO 8859/1 encoding.
Go is a safe, statically typed language. The code
board[r][col_ind] = int8(char)

is a failed attempt to correct errors when ISO 8859/1 encoding is decoded as UTF-8 encoding.
The decodeFen code is a &quot;stream-of-conciousness&quot; code that is hard to read and prove correct. The code is missing fundamental concepts like functions to encapsulate complexity and implementation details. For example, organize decodeFen as a series of calls to parse functions for each FEN field.

As an example, consider the FEN piece placement field. Here's a first draft:
pieces.go:
package main

import (
    &quot;errors&quot;
    &quot;fmt&quot;
    &quot;strings&quot;
)

type Board [8][8]byte

const (
    whitePieceLetters = &quot;PNBRQK&quot;
    blackPieceLetters = &quot;pnbrqk&quot;
    pieceLetters      = whitePieceLetters + blackPieceLetters
)

func isPiece(p byte) bool {
    for i := 0; i &lt; len(pieceLetters); i++ {
        if p == pieceLetters[i] {
            return true
        }
    }
    return false
}

var (
    ErrRankOutOfRange = errors.New(&quot;rank out of range&quot;)
    ErrFileOutOfRange = errors.New(&quot;file out of range&quot;)
    ErrPieceInvalid   = errors.New(&quot;piece invalid&quot;)
)

func parseFENPieces(board *Board, pieces string) error {
    ranks := strings.Split(pieces, &quot;/&quot;)
    if len(ranks) != len(board) {
        return ErrRankOutOfRange
    }
    for r, rank := range ranks {
        f := 0
        for i := 0; i &lt; len(rank); i++ {
            piece := rank[i]
            if piece &gt;= '0' &amp;&amp; piece &lt;= '9' {
                for j := byte(0); j &lt; piece-'0'; j++ {
                    if f &gt;= len(board[0]) {
                        return ErrFileOutOfRange
                    }
                    board[r][f] = '-'
                    f++
                }
            } else {
                if f &gt;= len(board[0]) {
                    return ErrFileOutOfRange
                }
                if !isPiece(piece) {
                    return ErrPieceInvalid
                }
                board[r][f] = piece
                f++
            }
        }
        if f != len(board[0]) {
            return ErrFileOutOfRange
        }
    }
    return nil
}

func main() {
    fens := []string{
        // https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation
        &quot;rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1&quot;,
        &quot;rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1&quot;,
        &quot;rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2&quot;,
        &quot;rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2&quot;,
    }
    var board Board
    for _, fen := range fens {
        fields := strings.Split(fen, &quot; &quot;)
        if len(fields) &gt; 0 {
            pieces := strings.Split(fen, &quot; &quot;)[0]
            fmt.Println(pieces)
            err := parseFENPieces(&amp;board, pieces)
            fmt.Println(err)
            for i := range board {
                fmt.Printf(&quot;%c\n&quot;, board[i])
            }
        }
    }
}

Playground: https://play.golang.org/p/-pPnCs2GMao
Output:
rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR
&lt;nil&gt;
[r n b q k b n r]
[p p p p p p p p]
[- - - - - - - -]
[- - - - - - - -]
[- - - - - - - -]
[- - - - - - - -]
[P P P P P P P P]
[R N B Q K B N R]

Use chess terminology to match the specification.
The chess board data structure is ubiquitous. Give it a type:
type Board [8][8]byte

In Go, arguments are passed by value. For an array, the value is the entire array. Therefore, for efficiency, we use a pointer (8 bytes or 4 bytes) rather than an array (64 bytes).
Input must be valid. Make no assumptions about external input. Report errors.
Don't use magic values: 49 is '0', 57 is '9'.
And so forth.